diff --git a/.gitignore b/.gitignore deleted file mode 100644 index d4c13020..00000000 --- a/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.DS_Store - -.idea - -VNote.pro.user -VNote.pro.user.* diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 970115b7..00000000 --- a/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "src/utils/marked"] - path = src/utils/marked - url = https://github.com/chjj/marked.git -[submodule "hoedown"] - path = hoedown - url = https://github.com/tamlok/hoedown.git diff --git a/.linux_bintray.json b/.linux_bintray.json deleted file mode 100644 index 47e77a33..00000000 --- a/.linux_bintray.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "package": { - "name": "vnote", - "repo": "vnote", - "subject": "tamlok", - "desc": "Continuous deployment by Travis-CI", - "website_url": "https://github.com/tamlok/vnote", - "issue_tracker_url": "https://github.com/tamlok/vnote/issues", - "vcs_url": "https://github.com/tamlok/vnote.git", - "github_use_tag_release_notes": false, - "github_release_notes_file": "", - "licenses": ["MIT"], - "labels": ["Markdown", "Note-Taking", "Office", "Utils", "Efficiency"], - "public_download_numbers": true, - "public_stats": true - }, - - "version": { - "name": "1.11", - "desc": "VNote Releases", - "released": "2017-12-17", - "vcs_tag": "1.11", - "gpgSign": false - }, - - "files": - [{"includePattern": "build/(VNote_.*\\.AppImage)", "uploadPattern": "$1", - "matrixParams": {"override": 1 }}], - - "publish": true -} diff --git a/.macos_bintray.json b/.macos_bintray.json deleted file mode 100644 index d01d6734..00000000 --- a/.macos_bintray.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "package": { - "name": "vnote", - "repo": "vnote", - "subject": "tamlok", - "desc": "Continuous deployment by Travis-CI", - "website_url": "https://github.com/tamlok/vnote", - "issue_tracker_url": "https://github.com/tamlok/vnote/issues", - "vcs_url": "https://github.com/tamlok/vnote.git", - "github_use_tag_release_notes": false, - "github_release_notes_file": "", - "licenses": ["MIT"], - "labels": ["Markdown", "Note-Taking", "Office", "Utils", "Efficiency"], - "public_download_numbers": true, - "public_stats": true - }, - - "version": { - "name": "1.11", - "desc": "VNote Releases", - "released": "2017-12-17", - "vcs_tag": "1.11", - "gpgSign": false - }, - - "files": - [{"includePattern": "build/distrib/(VNote_.*\\.dmg)", "uploadPattern": "$1", - "matrixParams": {"override": 1 }}], - - "publish": true -} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 805cc14c..00000000 --- a/.travis.yml +++ /dev/null @@ -1,59 +0,0 @@ -dist: trusty -sudo: required -git: - depth: 1 -language: cpp - -matrix: - include: - - os: osx - compiler: clang - osx_image: xcode8 - - os: linux - compiler: g++ - -branches: - only: - - master - -before_install: -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo apt-get -qq update ; fi -- export version="1.11" - -install: -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install p7zip-full ; fi -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install chrpath ; fi -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install openssl libssl-dev ; fi -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install libgl1-mesa-dev ; fi -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install tree ; fi -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo apt-get install -qq gcc-6; sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 100 ; fi -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo apt-get install -qq g++-6; sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-6 100 ; fi - -before_script: -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then chmod +x .travis_linux.sh ; fi -- if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then chmod +x .travis_macos.sh ; fi - -script: -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then CXX="g++-6" CC="gcc-6" ./.travis_linux.sh ; fi -- if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then ./.travis_macos.sh ; fi - -deploy: - - provider: bintray - file: "./.linux_bintray.json" - user: tamlok - key: - secure: vADlrYSusARnHxK3NTT3r1r6I/lrxyEuFKLOO73KXl6rvDywrrDDi6YsFekL14/o3clZKLOC8LbvA+4BKPVSoGTO4Dpx/i51fXphf+mMFB3QXSGnbqHm4+2ZnhCl62vfVlFeOPBLDO0KUBI8DCP0I+QogOUickXv3zYx69z6AudSxgjY7nPoN5jGSPgyId4r3o8Shrj1Fk1WtN6qciKyPne57v+jmvRlJTkoEfYkvwTRNMBlmaKy8Vj/CSoIvB8TH8bv3rhHLrN4o1QCwePdaX9G7xlImSpXqgRgzQVU3SRFN2bYTj5DZc1aFyA7iNOhmwgCLAN6OrqXyyJCbyywNhylfgad2rQANcfXiZw9ywooKEYafLDRuiK2G6Pk8m+R6Ded9JBoX9MSz/ZDxxfk4NmLO991wS7IK5aFTQfHZz5W8Tmh1rCphFwlDI/Rxs7ExbXu7INA8IhoLpOSmLIA5lfdC4fD8rv8mjy5gfpMkWlP8XATfi2eMH9uGj89aJa6xp7Bc2mfW3M71YHtYP/pyE/7Bk5vVonP8Cq9rK6OruMIUYtNmXoJnpte20ecSXj9yw7oTR27dhSx3XuAKOXiNpIau0CPxtXA5cSm5X0OS1Lt8RWrms0jp9Ch2dgxlNMpr0soF9DmwekhfHnVoOLyFBWBMDwvkx5TWij9FNAAJb4= - dry-run: false - on: - condition: $TRAVIS_OS_NAME = linux - branch: master - - provider: bintray - file: "./.macos_bintray.json" - user: tamlok - key: - secure: vADlrYSusARnHxK3NTT3r1r6I/lrxyEuFKLOO73KXl6rvDywrrDDi6YsFekL14/o3clZKLOC8LbvA+4BKPVSoGTO4Dpx/i51fXphf+mMFB3QXSGnbqHm4+2ZnhCl62vfVlFeOPBLDO0KUBI8DCP0I+QogOUickXv3zYx69z6AudSxgjY7nPoN5jGSPgyId4r3o8Shrj1Fk1WtN6qciKyPne57v+jmvRlJTkoEfYkvwTRNMBlmaKy8Vj/CSoIvB8TH8bv3rhHLrN4o1QCwePdaX9G7xlImSpXqgRgzQVU3SRFN2bYTj5DZc1aFyA7iNOhmwgCLAN6OrqXyyJCbyywNhylfgad2rQANcfXiZw9ywooKEYafLDRuiK2G6Pk8m+R6Ded9JBoX9MSz/ZDxxfk4NmLO991wS7IK5aFTQfHZz5W8Tmh1rCphFwlDI/Rxs7ExbXu7INA8IhoLpOSmLIA5lfdC4fD8rv8mjy5gfpMkWlP8XATfi2eMH9uGj89aJa6xp7Bc2mfW3M71YHtYP/pyE/7Bk5vVonP8Cq9rK6OruMIUYtNmXoJnpte20ecSXj9yw7oTR27dhSx3XuAKOXiNpIau0CPxtXA5cSm5X0OS1Lt8RWrms0jp9Ch2dgxlNMpr0soF9DmwekhfHnVoOLyFBWBMDwvkx5TWij9FNAAJb4= - dry-run: false - on: - condition: $TRAVIS_OS_NAME = osx - branch: master diff --git a/.travis_linux.sh b/.travis_linux.sh deleted file mode 100644 index f1acda01..00000000 --- a/.travis_linux.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/bin/bash -project_dir=$(pwd) - -# Install qt5.9 -sudo add-apt-repository ppa:george-edison55/cmake-3.x -y -sudo add-apt-repository ppa:beineri/opt-qt591-trusty -y -sudo apt-get update -qq -sudo apt-get -y install qt59base qt59webengine qt59webchannel qt59svg qt59location qt59tools qt59translations -source /opt/qt*/bin/qt*-env.sh - -# Compile newer version fcitx-qt5 -sudo apt-get -y install fcitx-libs-dev libgl1-mesa-dev bison -sudo apt-get -y install cmake - -wget http://xkbcommon.org/download/libxkbcommon-0.5.0.tar.xz -tar xf libxkbcommon-0.5.0.tar.xz -cd libxkbcommon-0.5.0 -./configure -prefix=/usr -libdir=/usr/lib/x86_64-linux-gnu -disable-x11 -make -j$(nproc) && sudo make install - -git clone git://anongit.kde.org/extra-cmake-modules -cd extra-cmake-modules -mkdir build && cd build -cmake .. -make -j$(nproc) && sudo make install - -git clone https://github.com/fcitx/fcitx-qt5 -cd fcitx-qt5 -git checkout 1.0.5 -cmake . -make -j$(nproc) && sudo make install - -# Copy fcitx-qt5 files to qt -sudo cp /usr/local/lib/libFcitxQt5DBusAddons.so* /opt/qt*/lib/ -sudo cp /usr/local/lib/libFcitxQt5WidgetsAddons.so* /opt/qt*/lib/ - -tree /opt/qt59/lib/ - -cd ${project_dir} -mkdir build -cd build -qmake -v -qmake CONFIG+=release -spec linux-g++-64 ../VNote.pro -make -j$(nproc) - -# -# Pack AppImage using linuxdeployqt -# -mkdir dist -INSTALL_ROOT=${project_dir}/build/dist make install ; tree dist/ - -# Copy SVG module -mkdir -p ./dist/usr/plugins/iconengines -mkdir -p ./dist/usr/plugins/imageformats -mkdir -p ./dist/usr/plugins/platforminputcontexts -cp /opt/qt59/plugins/iconengines/* ./dist/usr/plugins/iconengines/ -cp /opt/qt59/plugins/imageformats/* ./dist/usr/plugins/imageformats/ -cp /opt/qt59/plugins/platforminputcontexts/* ./dist/usr/plugins/platforminputcontexts/ - -# Copy other project files -cp "${project_dir}/README.md" "dist/README.md" -cp "${project_dir}/LICENSE" "dist/LICENSE" -echo ${version} > ./dist/version -echo "${TRAVIS_COMMIT}" >> ./dist/version - -# Get linuxdeployqt tool -wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" -chmod a+x linuxdeployqt*.AppImage -unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH -./linuxdeployqt*.AppImage ./dist/usr/share/applications/*.desktop -bundle-non-qt-libs - -# Copy translations -cp /opt/qt59/translations/*_zh_CN.qm ./dist/usr/translations/ - -# Package it for the second time. -./linuxdeployqt*.AppImage ./dist/usr/share/applications/*.desktop -appimage - -tree dist/ - -ls -l *.AppImage - -mv VNote-*.AppImage VNote_x86_64_${version}.AppImage - -cd .. - -exit 0 diff --git a/.travis_macos.sh b/.travis_macos.sh deleted file mode 100644 index 7eac2712..00000000 --- a/.travis_macos.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash -project_dir=$(pwd) - -brew update > /dev/null -brew install qt -QTDIR="/usr/local/opt/qt" -PATH="$QTDIR/bin:$PATH" -LDFLAGS=-L$QTDIR/lib -CPPFLAGS=-I$QTDIR/include - -# Build your app -cd ${project_dir} -mkdir build -cd build -qmake -v -qmake CONFIG-=debug CONFIG+=release ../VNote.pro -make -j2 - -git clone https://github.com/aurelien-rainone/macdeployqtfix.git - -# Package DMG from build/src/VNote.app directory -cd src/ - -sed -i -e 's/com.yourcompany.VNote/com.tamlok.VNote/g' VNote.app/Contents/Info.plist -$QTDIR/bin/macdeployqt VNote.app -python ../macdeployqtfix/macdeployqtfix.py VNote.app/Contents/MacOS/VNote $QTDIR - -# Fix Helpers/QtWebEngineProcess.app -cd VNote.app/Contents/Frameworks/QtWebEngineCore.framework/Versions/5/Helpers -$QTDIR/bin/macdeployqt QtWebEngineProcess.app -python ${project_dir}/build/macdeployqtfix/macdeployqtfix.py QtWebEngineProcess.app/Contents/MacOS/QtWebEngineProcess $QTDIR - -cd ${project_dir}/build -mkdir -p distrib/VNote -cd distrib/VNote -mv ../../src/VNote.app ./ -cp "${project_dir}/LICENSE" "LICENSE" -cp "${project_dir}/README.md" "README.md" -echo "${version}" > version -echo "${TRAVIS_COMMIT}" >> version - -ln -s /Applications ./Applications - -cd .. -hdiutil create -srcfolder ./VNote -format UDBZ ./VNote.dmg -mv VNote.dmg VNote_X64_${version}.dmg -cd .. - -exit 0 diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 401b9948..00000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 Le Tan - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100644 index c3e3b939..00000000 --- a/README.md +++ /dev/null @@ -1,223 +0,0 @@ -# VNote -[中文 Chinese](./README_zh.md) - -Designed specially for **Markdown**, **VNote** is a Vim-inspired note-taking application, which knows programmers and Markdown better. - -![VNote](screenshots/vnote.png) - -# Downloads -Users from China can download the latest release of VNote from [Baidu Netdisk](http://pan.baidu.com/s/1jI5HROq). - -## Windows -![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/tamlok/vnote?svg=true) - -- [Github releases](https://github.com/tamlok/vnote/releases) -- Latest builds on master: [ ![Download](https://api.bintray.com/packages/tamlok/vnote/vnote/images/download.svg) ](https://bintray.com/tamlok/vnote/vnote/_latestVersion) - -**NOT** supported in XP since QtWebEngineProcess used by VNote could not work in XP. - -## Linux - -### AppImage -[![Build Status](https://travis-ci.org/tamlok/vnote.svg?branch=master)](https://travis-ci.org/tamlok/vnote) - -There is an AppImage format standalone executable of VNote for major Linux distributions. **Any help for packaging and distribution on Linux is appreciated!** - -- [Github releases](https://github.com/tamlok/vnote/releases) -- Latest builds on master: [ ![Download](https://api.bintray.com/packages/tamlok/vnote/vnote/images/download.svg) ](https://bintray.com/tamlok/vnote/vnote/_latestVersion) - -### openSUSE -Currently `vnote` on openSUSE Tumbleweed can be installed from `home:opensuse_zh` project on OBS. You can execute the following command directly: - -```shell -sudo zypper ar https://download.opensuse.org/repositories/home:/opensuse_zh/openSUSE_Tumbleweed/ home:opensuse_zh -sudo zypper ref -sudo zypper in vnote -``` - -For other architectures, please search for `vnote` at [software.opensuse.org](https://software.opensuse.org). - -We don't support Leap 42 and below due to the Qt version. Please use AppImage or build it yourself. - -## MacOS -[![Build Status](https://travis-ci.org/tamlok/vnote.svg?branch=master)](https://travis-ci.org/tamlok/vnote) - -- [Github releases](https://github.com/tamlok/vnote/releases) -- Latest builds on master: [ ![Download](https://api.bintray.com/packages/tamlok/vnote/vnote/images/download.svg) ](https://bintray.com/tamlok/vnote/vnote/_latestVersion) - -# Description -**VNote** is a Qt-based, free and open source note-taking application, focusing on Markdown. VNote is designed to provide comfortable edit experience. - -VNote is **NOT** just a simple editor for Markdown. By providing notes management, VNote makes taking notes in Markdown simpler and more pleasant. - -Utilizing Qt, VNote could run on **Linux**, **Windows**, and **macOS**. - -![VNote](screenshots/_vnote_1513485003_1746530034.png) - -# Supports -- [Github issues](https://github.com/tamlok/vnote/issues); -- Email: tamlokveer at gmail.com; -- QQ group: 487756074; -- WeChat Public Account: VNote笔记 (vnote_md); -![VNote WeChat](screenshots/vnote_md.jpg) - -# Highlights -- Supports inserting images directly from clipboard; -- Supports syntax highlights of fenced code blocks in both **edit** and **read** mode; -- Supports outline in both edit and read mode; -- Supports custom styles in both edit and read mode; -- Supports Vim mode and a set of powerful shortcuts; -- Supports infinite levels of folders; -- Supports multiple tabs and splitting windows; -- Supports [Mermaid](http://knsv.github.io/mermaid/), [Flowchart.js](http://flowchart.js.org/), and [MathJax](https://www.mathjax.org/); -- Supports HiDPI; -- Supports attachments of notes. -- Supports themes and dark mode. - -# Why VNote -## Markdown Editor & Notes Management -VNote tries to be a powerful Markdown editor with notes management, or a note-taking application with pleasant Markdown support. If you are a fan of Markdown and enjoy writing Markdown notes for study, work, and life, VNote is the right tool for you. - -## Pleasant Markdown Experience -### Insight About Markdown -Markdown, as a simple mark language, unlike rich text, was born with a **gap between edit and read**. There are about three ways to handle this gap: - -1. As one extreme, some editors just tread Markdown as **plain text**. Users may lose themselves in the messy black characters. It is hard to keep track of the information of the note. -2. Most Markdown editors use two panels to **edit and preview Markdown notes simultaneously**. It makes things easier since users could see a pleasant typesetting and layout while editing the text. However, two panels may occupy the whole screen and users keep moving eyes left and righti which will be a big distraction. -3. As another extreme, some editors convert the Markdown elements in place immediately after the typing, which makes editing Markdown just like editing rich text document in Word. - -Since most editors choose the second way to handle the gap, people always think of preview when it comes to Markdown. It may be a misunderstanding about Markdown. Designed as a simple mark language, Markdown is intended to help to keep track of the information of the text when editing and provide a beautiful typesetting when reading after being converted to HTML. - -### Tradeoff: VNote's Way -VNote tries to minimize the gap and provide the best-effort *WYSIWYG* for Markdown via tuned **syntax highlights** and some other features. By helping to keep track of the content, there is no need to preview or alter the text immediately after being typed. - -# Features -## Notebook-Based Notes Management -VNote uses **notebooks** to hold your notes. Like OneNote, a notebook can be hosted on any location on your system. A notebook is designed to represent one account. For example, you could have one notebook hosted on local file system and another notebook hosted on an OwnCloud server. This is really useful when notes require different levels of security. - -A notebook corresponds to a self-contained folder (called the *Root Folder* of the notebook) in the file system. You could copy the folder to another location (or on another computer) and import it into VNote. - -A notebook could have infinite levels of folders. VNote supports copying or moving folders or notes within or between notebooks. - -## Simple Notes Management -All your notes are managed by some plaintext configuration files and stored as plaintext files. You could access your notes without VNote. You could use external file synchronization services to synchronize your notes and import them on another machine. - -VNote supports both Markdown (suffix `md`) and rich text notes. - -## Syntax Highlight -VNote supports accurate syntax highlight for Markdown. Tuning the style of the highlight, VNote enables you to keep track of your document easily. - -VNote also supports **syntax highlight for fenced code blocks** in edit mode in Markdown, which is **superior** than almost all current Markdown editors. - -![Syntax Highlight](screenshots/_1513485266_1616037517.png) - -## Live Image Preview -VNote supports previewing the image link in edit mode. With this, you could just stay in edit mode as much as possible. - -![Live Image Preview](screenshots/_1513485934_140085443.png) - -## Pleasant Image Experience -Just paste your image into the Markdown note, VNote will manage all other stuffs. VNote stores images in a specified folder in the same folder with the note. VNote will pop up a window to preview the image when you insert an image. Furthermore, VNote will delete the useless image files automatically after you remove the image links. - -![](screenshots/_1513485753_394180887.png) - -## Interactive Outline Viewer In Read & Edit Mode -VNote provides a user-friendly outline viewer for both edit and view mode. The outline viewer is a responsive item tree instead of a segment of HTML. - -## Powerful Shortcuts -VNote supports many pleasant and powerful shortcuts which facilitate your editing, including **Vim Mode**, **Captain Mode**, and **Navigation Mode** which enable you to work without the mouse. - -Please refer to the [shortcuts help](src/resources/docs/shortcuts_en.md) in the help menu for more details. - -## Highly Configurable -In VNote, almost everything is configurable, such as background color, font, and Markdown style. VNote uses a plaintext file to record all your configuration, so you could just copy that file to initialize a new VNote on another computer. - -## Others -VNote also supports many other features, like: - -- Highlight current cursor line; -- Highlight selected text; -- Powerful search within the note; -- Auto indent and auto list; - -# Build & Development -VNote needs Qt 5.9.1 or above to build. - -1. Clone & Init - ``` - git clone https://github.com/tamlok/vnote.git vnote.git - cd vnote.git - git submodule update --init - ``` -2. Download Qt & Have Fun -Download [Qt 5.9.1](http://info.qt.io/download-qt-for-application-development) and open `VNote.pro` as a project. - -## Linux -If your distribution does not have Qt 5.9.1 or above, you need to add it from other sources. In Ubuntu, you could do this: - -``` -sudo add-apt-repository ppa:beineri/opt-qt591-trusty -y -sudo apt-get update -qq -sudo apt-get -y install qt59base qt59webengine qt59webchannel qt59svg qt59location qt59tools qt59translations -source /opt/qt*/bin/qt*-env.sh -``` - -After Qt and some necessary modules are ready, you could follow these steps to build VNote - -``` -cd vnote.git -mkdir build -cd build -qmake ../VNote.pro -make -sudo make install -``` - -For details, you could reference [.travis_linux.sh](.travis_linux.sh) in the source root. - -## MacOS -If you prefer command line on macOS, you could follow these steps. - -1. Install Xcode and Homebrew; -2. Install Qt 5.9.1 via Homebrew: - ``` - brew install qt@5.9.1 - ``` -3. In the project directory, create `build_macos.sh` like this: - ```sh - QTDIR="/usr/local/opt/qt@5.9.1" - PATH="$QTDIR/bin:$PATH" - LDFLAGS=-L$QTDIR/lib - CPPFLAGS=-I$QTDIR/include - - mkdir -p build - cd build - qmake -v - qmake CONFIG-=debug CONFIG+=release ../VNote.pro - make -j2 - ``` -4. Make `build_macos.sh` executable and run it: - ```sh - chmod +x build_macos.sh - ./build_macos.sh - ``` -5. Now you got the bundle `path/to/project/build/src/VNote.app`. Enjoy yourself! - -# Dependencies -- [Qt 5.9](http://qt-project.org) (L-GPL v3) -- [PEG Markdown Highlight](http://hasseg.org/peg-markdown-highlight/) (MIT License) -- [Hoedown 3.0.7](https://github.com/hoedown/hoedown/) (ISC License) -- [Marked](https://github.com/chjj/marked) (MIT License) -- [Highlight.js](https://github.com/isagalaev/highlight.js/) (BSD License) -- [Ionicons 2.0.1](https://github.com/driftyco/ionicons/) (MIT License) -- [markdown-it 8.3.1](https://github.com/markdown-it/markdown-it) (MIT License) -- [markdown-it-headinganchor 1.3.0](https://github.com/adam-p/markdown-it-headinganchor) (MIT License) -- [markdown-it-task-lists 1.4.0](https://github.com/revin/markdown-it-task-lists) (ISC License) -- [mermaid 7.0.0](https://github.com/knsv/mermaid) (MIT License) -- [MathJax](https://www.mathjax.org/) (Apache-2.0) -- [showdown](https://github.com/showdownjs/showdown) (Unknown) -- [flowchart.js](https://github.com/adrai/flowchart.js) (MIT License) -- Icons made by a326703305@qq.com - -# License -VNote is licensed under the [MIT license](http://opensource.org/licenses/MIT). diff --git a/README_zh.md b/README_zh.md deleted file mode 100644 index d589d147..00000000 --- a/README_zh.md +++ /dev/null @@ -1,229 +0,0 @@ -# VNote -[英文 English](./README.md) - -**VNote** 是一个受Vim启发开发的专门为 **Markdown** 而优化、设计的笔记软件。VNote是一个更了解程序员和Markdown的笔记软件。 - -![VNote](screenshots/vnote.png) - -# 下载 -国内的用户可以尝试在[百度云盘](http://pan.baidu.com/s/1jI5HROq)下载VNote的最新发行版本。 - -## Windows -![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/tamlok/vnote?svg=true) - -- [Github releases](https://github.com/tamlok/vnote/releases) -- master分支的最新构建:[ ![Download](https://api.bintray.com/packages/tamlok/vnote/vnote/images/download.svg) ](https://bintray.com/tamlok/vnote/vnote/_latestVersion) - -VNote不支持**XP**,因为QtWebEngineProcess无法在XP上运行。 - -## Linux - -### AppImage -[![Build Status](https://travis-ci.org/tamlok/vnote.svg?branch=master)](https://travis-ci.org/tamlok/vnote) - -VNote当前为主要Linux发行版提供了一个AppImage格式的独立可执行文件。希望了解Linux系统下打包发布的开发人员能提供这方面进一步的帮助! - -- [Github releases](https://github.com/tamlok/vnote/releases) -- master分支的最新构建:[ ![Download](https://api.bintray.com/packages/tamlok/vnote/vnote/images/download.svg) ](https://bintray.com/tamlok/vnote/vnote/_latestVersion) - -### openSUSE -目前 openSUSE Tumbleweed 可以通过 OBS 上的 `home:opensuse_zh` 源直接安装。您可以直接执行以下命令: - -```shell -sudo zypper ar https://download.opensuse.org/repositories/home:/opensuse_zh/openSUSE_Tumbleweed/ home:opensuse_zh -sudo zypper ref -sudo zypper in vnote -``` - -其他架构请直接在 [software.opensuse.org](https://software.opensuse.org) 搜索 `vnote`。 - -由于 Leap 42 及以下版本的 Qt 版本过低,我们无法在 OBS 上进行打包。请使用 AppImage 或自行构建。 - -## MacOS -[![Build Status](https://travis-ci.org/tamlok/vnote.svg?branch=master)](https://travis-ci.org/tamlok/vnote) - -- [Github releases](https://github.com/tamlok/vnote/releases) -- master分支的最新构建:[ ![Download](https://api.bintray.com/packages/tamlok/vnote/vnote/images/download.svg) ](https://bintray.com/tamlok/vnote/vnote/_latestVersion) - -# 简介 - -**VNote**是一个基于Qt框架的、免费的开源笔记软件。VNote专注于Markdown的编辑与阅读,以提供舒适的编辑体验为设计目标。 - -VNote不是一个简单的Markdown编辑器。通过提供笔记管理功能,VNote使得编写Markdown笔记更简单和舒适! - -基于Qt框架,VNote能够在主流操作系统上运行,包括 **Linux**, **Windows** 以及 **macOS**(由于macOS上很不一样的交互逻辑,VNote在macOS上并没有被充分测试,我们也希望得到更多的反馈以帮助改进VNote)。 - -![VNote](screenshots/_vnote_1513485003_1746530034.png) - -# 支持 -- [Github issues](https://github.com/tamlok/vnote/issues); -- 邮箱: tamlokveer at gmail.com; -- QQ群: 487756074; -- 微信公众号: VNote笔记(vnote_md); -![VNote WeChat](screenshots/vnote_md.jpg) - -# 亮点 -- 支持直接从剪切板插入图片; -- 支持编辑和阅读模式下代码块的语法高亮; -- 支持编辑和阅读模式下的大纲; -- 支持自定义编辑和阅读模式的样式; -- 支持Vim模式以及一系列强大的快捷键; -- 支持无限层级的文件夹; -- 支持多个标签页和窗口分割; -- 支持[Mermaid](http://knsv.github.io/mermaid/), [Flowchart.js](http://flowchart.js.org/) 和 [MathJax](https://www.mathjax.org/); -- 支持高分辨率; -- 支持笔记附件。 -- 支持主题以及深色模式; - -# 开发VNote的动机 -## Markdown编辑器与笔记管理 -VNote设计为带有笔记管理功能的Markdown编辑器,或者有良好Markdown支持的笔记软件。如果您喜欢Markdown并经常在学习、工作和生活中使用Markdown记录笔记,那么VNote就是一个适合您的工具。 - -## 舒适的Markdown体验 -### Markdown的本质 -Markdown作为一个简单标记语言,不像富文本,它的编辑和阅读有着与生俱来的隔阂。一般目前大概有三类方法来处理这个隔阂: - -1. 作为一个极端,一些编辑器只是将Markdown作为无格式的纯文本处理。用户很容易在密密麻麻的黑漆漆的一片文字中找不着方向。 -2. 大部分编辑器使用两个面板来同时编辑和预览Markdown笔记。从而,用户可以在编辑的同时看到优美的排版和布局。但是,两个面板基本会占据了整个屏幕,而用户的目光焦点左右频繁移动,往往也会使得用户无法专注编辑。 -3. 作为另一个极端,一些编辑器在用户输入文本后立即将Markdown的标记转换为HTML元素,使得编写Markdown如同在Word文档里面编写富文本一样。 - -由于几乎所有的编辑器都选择第二种方法来处理隔阂,一提到Markdown人们往往会想起预览。这可能是对Markdown的一个最大的误解了。设计为一个简单的标记语言,Markdown的设计初衷就是为了在编辑的时候方便帮助跟踪文本的信息,而又能在阅读的时候被转换为HTML为发布提供美观的排版输出。所以,Markdown本身就应该在编辑的时候能够方便地跟踪和掌控文本的信息和脉络,而不需要通过预览这种接近饮鸩止渴的方法来方便编辑。 - -### 折中:VNote的方案 -VNote尝试通过精心调配的**语法高亮**和其他一些特性,来最大程度地减小Markdown的这种割裂感,尽可能地提供一个*所见即所得*的编辑体验。用户在编辑的时候就能有效第把握内容脉络,也就没有必要进行预览或者强制更改文本为HTML元素了。 - -# 功能 -## 基于笔记本的管理 -VNote使用 **笔记本** 来管理笔记。类似于OneNote,一个笔记本可以保存在系统上的任意位置。一个笔记本对应于一个账户的概念。例如,您可以在本地文件系统上有一个笔记本,另外在某台OwnCloud服务器上保存另一个笔记本。当不同的笔记有不同的保密要求时,独立的笔记本就非常适用了。 - -一个笔记本对应于文件系统上的一个独立完整的文件夹(称为笔记本的 **根目录** )。您可以将该文件夹拷贝到其他位置(或者另一台计算机上),然后将其导入到VNote中。 - -VNote支持一个笔记本中包含无限层级的文件夹。VNote支持在笔记本内或笔记本间拷贝或剪切文件夹和笔记。 - -## 直观的笔记管理 -所有笔记被保存为纯文本而且通过纯文本的配置文件进行管理。即使没有VNote,您也能方便访问您的数据。这样,您也可以使用第三方的文件同步服务来同步您的笔记,并在另一台计算机上导入到VNote中。 - -VNote支持Markdown和富文本笔记,其中Markdown笔记必须以`md`为后缀名。 - -## 语法高亮 -VNote支持精确的Markdown语法高亮。通过精心调试的高亮样式,VNote使得您能够轻松跟踪和阅读您的文档。 - -VNote还支持Markdown编辑模式中代码块的语法高亮。目前的Markdown编辑器中绝大部分都尚不支持该特性。 - -![Syntax Highlight](screenshots/_1513485266_1616037517.png) - -## 实时图片预览 -VNote支持在编辑时原地预览图片链接。这样一来,您就能尽可能地留在编辑模式,避免频繁切换。 - -如果想要拷贝图片,可以选取该图片,然后复制。 - -![Live Image Preview](screenshots/_1513485934_140085443.png) - -## 良好的图片体验 -编辑时,支持像其他富文本编辑器一样直接粘贴插入图片,VNote会帮您管理所插入的图片。VNote将这些图片保存在和笔记同一目录下的一个指定目录中。插入图片时,VNote会弹出一个窗口预览即将要插入的图片。另外,当您移除笔记中的图片链接时,VNote会自动删除对应的图片文件。 - -![](screenshots/_1513485753_394180887.png) - -## 编辑和阅读模式中的交互式大纲视图 -VNote为编辑和预览模式都提供了一个用户友好的大纲视图。该大纲视图是一个项目树,而不是简单地插入一段HTML。 - -## 强大的快捷键 -VNote提供很多快捷键,从而提供一个愉悦的编辑体验。其中包括 **Vim模式**、**舰长模式** 和 **导航模式**,它们能让您完全摆脱鼠标进行操作。 - -更多细节请参考帮助菜单中的[快捷键帮助](src/resources/docs/shortcuts_zh.md)。 - -## 高度可定制 -VNote中,几乎一切都是可以定制的,例如背景颜色、字体以及Markdown样式等。VNote使用一个纯文本文件来记录您的所有配置,因此通过拷贝该文件就能够很快地在另一台电脑上初始化一个新的VNote。 - -## 其他 -VNote还支持其他很多的功能,比如: - -- 高亮当前行; -- 高亮所选择的文本; -- 强大的页内查找; -- 自动缩进和自动列表; - -# 构建与开发 -VNote需要5.9.1版本以上的Qt进行构建。 - -1. 克隆代码仓库 - ``` - git clone https://github.com/tamlok/vnote.git vnote.git - cd vnote.git - git submodule update --init - ``` -2. 下载Qt -下载[Qt 5.9.1](http://info.qt.io/download-qt-for-application-development),导入`VNote.pro`创建一个工程。 - -## Linux -如果您的Linux发行版不提供5.9.1以上版本的Qt,那么您需要从其他来源获取Qt。在Ubuntu中,您可以执行以下步骤: - -``` -sudo add-apt-repository ppa:beineri/opt-qt591-trusty -y -sudo apt-get update -qq -sudo apt-get -y install qt59base qt59webengine qt59webchannel qt59svg qt59location qt59tools qt59translations -source /opt/qt*/bin/qt*-env.sh -``` - -当Qt和相关的模块准备就绪后,您可以执行以下命令来编译和安装: - -``` -cd vnote.git -mkdir build -cd build -qmake ../VNote.pro -make -sudo make install -``` - -更多细节,您可以参考源代码根目录下的 [.travis_linux.sh](.travis_linux.sh) 。 - -## MacOS -在macOS下,您可以执行以下步骤来编译: - -1. 安装Xcode和Homebrew: -2. 通过Homebrew安装Qt5.9.1: - - ``` - brew install qt@5.9.1 - ``` -3. 在VNote源码根目录下,新建一个文件`build_macos.sh`: - - ```sh - QTDIR="/usr/local/opt/qt@5.9.1" - PATH="$QTDIR/bin:$PATH" - LDFLAGS=-L$QTDIR/lib - CPPFLAGS=-I$QTDIR/include - - mkdir -p build - cd build - qmake -v - qmake CONFIG-=debug CONFIG+=release ../VNote.pro - make -j2 - ``` -4. 修改`build_macos.sh`的执行权限,并执行: - - ```sh - chmod +x build_macos.sh - ./build_macos.sh - ``` -5. 此时得到VNote的Bundle `path/to/project/build/src/VNote.app`,打开即可。 - -# 依赖 -- [Qt 5.9](http://qt-project.org) (L-GPL v3) -- [PEG Markdown Highlight](http://hasseg.org/peg-markdown-highlight/) (MIT License) -- [Hoedown 3.0.7](https://github.com/hoedown/hoedown/) (ISC License) -- [Marked](https://github.com/chjj/marked) (MIT License) -- [Highlight.js](https://github.com/isagalaev/highlight.js/) (BSD License) -- [Ionicons 2.0.1](https://github.com/driftyco/ionicons/) (MIT License) -- [markdown-it 8.3.1](https://github.com/markdown-it/markdown-it) (MIT License) -- [markdown-it-headinganchor 1.3.0](https://github.com/adam-p/markdown-it-headinganchor) (MIT License) -- [markdown-it-task-lists 1.4.0](https://github.com/revin/markdown-it-task-lists) (ISC License) -- [mermaid 7.0.0](https://github.com/knsv/mermaid) (MIT License) -- [MathJax](https://www.mathjax.org/) (Apache-2.0) -- [showdown](https://github.com/showdownjs/showdown) (Unknown) -- [flowchart.js](https://github.com/adrai/flowchart.js) (MIT License) -- 图标由九梦岛主(a326703305@qq.com)制作 - -# 代码许可 -VNote使用[MIT许可](http://opensource.org/licenses/MIT)。 diff --git a/VNote.pro b/VNote.pro deleted file mode 100644 index 4adc516d..00000000 --- a/VNote.pro +++ /dev/null @@ -1,15 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2016-10-01T11:03:59 -# -#------------------------------------------------- - -TEMPLATE = subdirs - -CONFIG += c++11 - -SUBDIRS = hoedown \ - peg-highlight \ - src - -src.depends = hoedown peg-highlight diff --git a/_config.yml b/_config.yml deleted file mode 100644 index c4192631..00000000 --- a/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-cayman \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 910b70e2..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,76 +0,0 @@ -image: Visual Studio 2015 - -version: 1.11.{build} - -branches: - only: - - master - -environment: - COMPILER: msvc - VSVER: 14 - - matrix: - - QT: C:\Qt\5.9\msvc2015_64 - PLATFORM: amd64 - - QT: C:\Qt\5.9\msvc2015 - PLATFORM: x86 - -clone_depth: 1 - -# scripts that run after cloning repository -install: - - set PATH=%QT%\bin\;C:\Qt\Tools\QtCreator\bin\;C:\Qt\QtIFW2.0.1\bin\;%PATH% - - git submodule update --init --recursive - -# scripts that run before build -before_build: - - call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %PLATFORM% - # After calling vcvarsall.bat, %PLATFORM% will be X64 or x86 - - qmake --version - - mkdir build - - cd build - - if "%PLATFORM%" EQU "X64" (qmake -r -spec win32-msvc CONFIG+=x86_64 CONFIG-=debug CONFIG+=release ../VNote.pro) - - if "%PLATFORM%" EQU "x86" (qmake -r -spec win32-msvc CONFIG+=Win32 CONFIG-=debug CONFIG+=release ../VNote.pro) - -# custom build scripts -build_script: - - nmake - -# scripts that run after build -after_build: - - set vnote_version=1.11 - # Clone OpenSSL DLLs - - git clone https://github.com/tamlok/openssl-utils.git openssl-utils.git - - mkdir distrib\VNote - - windeployqt.exe --dir .\distrib\VNote %APPVEYOR_BUILD_FOLDER%\build\src\release\VNote.exe - - copy "%APPVEYOR_BUILD_FOLDER%\build\src\release\VNote.exe" "distrib\VNote\VNote.exe" - - copy "%APPVEYOR_BUILD_FOLDER%\README.md" "distrib\VNote\README.md" - - copy "%APPVEYOR_BUILD_FOLDER%\LICENSE" "distrib\VNote\LICENSE.txt" - - echo %vnote_version% > "distrib\VNote\version.txt" - - echo %APPVEYOR_REPO_COMMIT% >> "distrib\VNote\version.txt" - - copy "distrib\VNote\VNote.exe" "distrib\VNote_win_%PLATFORM%.exe" - # Copy OpenSSL DLLs - - if "%PLATFORM%" EQU "X64" (xcopy "openssl-utils.git\win64\*.dll" "distrib\VNote") - - if "%PLATFORM%" EQU "x86" (xcopy "openssl-utils.git\win32\*.dll" "distrib\VNote") - - cd distrib - - 7z a VNote_win_%PLATFORM%_portable_%vnote_version%.zip VNote - -artifacts: - - path: build\distrib\VNote_win_%PLATFORM%_portable_%vnote_version%.zip - name: portable - - path: build\distrib\VNote_win_%PLATFORM%.exe - name: exe_only - -deploy: - - provider: BinTray - username: tamlok - api_key: - secure: YJqzsVDlC2NYH2RgzbUMtjZWbSXOdWUiiENOIqImo31hOfeiB0MiVGmBLmKPAHEg - subject: tamlok - repo: vnote - package: vnote - version: 1.11 - publish: true - override: true - artifact: portable diff --git a/changes.md b/changes.md deleted file mode 100644 index 7178aa2f..00000000 --- a/changes.md +++ /dev/null @@ -1,143 +0,0 @@ -# Changes History -## v1.11 -- Support themes; - - Three built-in mordern themes; - - One dark mode theme; -- Vim mode - - Support block cursor in Normal/Visual mode; - - `=` to auto-indent selected lines as the first line; -- Support custom external editors to open notes; -- Enable `Ctrl+C`/`Ctrl+V` in Vim mode to copy/paste; -- Support Flash Page to record ideas quickly; -- Support previewing inline images; - -## v1.10 -- Migrate to Qt 5.9.1; -- Support Compact mode in main window; -- Update icons; -- Support custom startup pages; -- Remove obsolete title marker when inserting new one; -- Support Magic Words; -- Vim mode - - Share registers among all tabs; - - Support `Ctrl+O` in Insert mode; -- Add "Code Block", "Insert Link", and "Insert Image" tool bar buttons; -- Support `Ctrl+Shift+T` to recover last closed tabs; -- Support view read-only files in edit mode; -- Refactor editor for speed; -- Support templates when creating notes; -- Support snippets; -- Support file change check; -- Support backup file (save changes automatically); - -## v1.9 -- Support attachments of notes. -- Add recycle bin to notebook to hold deleted files. -- Refine Vim mode: - - Support J and gJ to join line; - - Support S, {, and }; - - w to save note; - - Fix Y and D actions in Visual mode. -- Support AppImage package for Linux. -- More responsive and efficient syntax highlight and image preview. -- More pleasant line distance. -- More natural interaction of folder and note management. -- Support inserting note name as title. -- Support custom default mode to open a note. -- Support auto heading sequence. -- Support color column in fenced code block in edit mode. -- Support line number in code block in both read and edit mode. -- Support created time and modified time of notes, folders, and notebooks. -- Support custom Markdown-it options, such as auto line break. -- Confirm when cleaning up unused images. -- Support custom Mathjax location. -- Support custom style for code block highlights in read mode. -- Double click on a tab to close it. - -## v1.8 -- Support editing external files. VNote could open files from command line. -- Support drag-and-drop to open external files. -- Refine tab context menu. -- Support system tray icon. -- Refine Vim mode. -- Make all tool buttons always visible and smaller. -- Support custom file type suffix. -- Make the name of notebook/folder/note case-insensitive. -- Support links to internal notes in notes. - -## v1.7 -- ATTENTION: please add font-size option to the "editor" section of your custom MDHL style. -- Refine Vim mode (more functions, please refer to the shortcuts help). -- Support Find in Vim mode. -- Refine tab context menu. -- Support Flowchart.js for flowchart. -- Add toolbar for common text edit functions. -- Support line number (both absolute and relative) in edit mode. -- Support custom shortcuts. -- Support [[, ]], [], ][, [{, ]} to navigate through titles in both edit and read mode. -- Many minor bug fixes. - -## v1.6 -- Support simple but powerful **Vim mode**. -- Change the shortcut of ExitAndRead from `Ctrl+R` to `Ctrl+T`. -- Add a edit status indicator in the status bar. -- Dragging mouse with Ctrl and left button pressed to scroll in read and edit mode. -- Refine highlighting cursor line. -- Support subscript, superscript and footnote in markdown-it renderer. -- Refactor outline logics to not show extra [EMPTY] headers. -- Handle HTML comments correctly. -- Provide a default root folder when adding notebooks. -- Support check for updates. -- Redraw app icons. -- Many minor bug fixes. - -## v1.5 -- Support logging in release mode. -- Fix Chinese font matching in mdhl. -- Fix VimagePreviewer to support optional title. -- Refactor local image folder logics. -- Support custom local image folder for both notebook scope and global scope. -- Support constraining the width of images in read mode. -- Fix and refine default style. -- Centering the images and display the alt text as caption in read mode. -- Support exporting a single note as PDF file. -- Add "Open File Location" menu item in folder tree and note list. -- Support highlighting trailing space. - -## v1.4 -- Use `_vnote.json` as the config file. -- More user friendly messages. -- Delete notebook by deleting root directories one by one. -- Refactor image preview logics to support previewing all images in edit mode. -- Support constraining the width of previewed images to the edit window. -- bugfix. - -## v1.3 -- Support code block syntax highlight in edit mode. -- A more pleasant AutoIndent and AutoList. -- `Ctrl+` instead of `Ctrl+Alt+` to insert title. -- Support custom Markdown CSS styles and editor styles. - -## v1.2 -- Support **MathJax**. -- Fix a crash on macOS. -- Change default font family. -- Refine tab order. -- Better support for HiDPI. -- Support zoom in/out page when reading. -- Introduce **Captain Mode** and **Navigation Mode**. -- A more user friendly popup opened notes list. -- Support jumping to specified tab efficiently by num keys. -- Add shortcuts documentation. -- AutoList and AutoIndent. - -## v1.1 -- Refine messages and dialogs. Add Chinese translations. -- A new application icon. -- Support install target for Linux. -- Continuous build and deployment for Linux, macOS, and Windows. -- Support both X64 and x86 version of Windows. -- Add `.md` suffix automatically when creating a note. -- A more user friendly insert dialog. -- Support **Mermaid** diagram. -- Add **markdown-it** as the default renderer. Support task list. diff --git a/css/froala_blocks.css b/css/froala_blocks.css new file mode 100644 index 00000000..b91a4505 --- /dev/null +++ b/css/froala_blocks.css @@ -0,0 +1,262 @@ +.btn { + padding: 9px 26px; + background-color: #528bff; + color: #FFF; + display: inline-block; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + text-decoration: none; + border: solid 2px #528bff; + border-radius: 2px; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; } + .btn.btn-empty { + background-color: transparent; + color: #528bff; } + .btn:hover { + color: #FFF; + background-color: #1f69ff; + border-color: #1f69ff; } + .btn.btn-black { + color: #FFFFFF; + background-color: #000000; + border-color: #000000; } + .btn.btn-black.btn-empty { + background-color: transparent; + color: #000000; } + .btn.btn-black:hover { + color: #FFF; + background-color: #0d0d0d; + border-color: #0d0d0d; } + .btn.btn-white { + color: #000000; + background-color: #FFFFFF; + border-color: #FFFFFF; } + .btn.btn-white.btn-empty { + background-color: transparent; + color: #FFFFFF; } + .btn.btn-white:hover { + color: #000000; + background-color: #DEDEDE; + border-color: #DEDEDE; } + .btn.btn-shadow { + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); } + .btn.btn-round { + border-radius: 20px; + -moz-border-radius: 20px; + -webkit-border-radius: 20px; + min-width: 150px; } + +.team-1.fdb-block img { + border-bottom: solid 5px #528bff; + border-radius: 0 !important; + -moz-border-radius: 0 !important; + -webkit-border-radius: 0 !important; } + +.team-1.fdb-block .fdb-box { + padding: 0; } + .team-1.fdb-block .fdb-box .content { + padding: 20px; } + +.team-2.fdb-block img { + border-radius: 100% !important; + -moz-border-radius: 100% !important; + -webkit-border-radius: 100% !important; } + +.team-3.fdb-block img { + border-radius: 100% !important; + -moz-border-radius: 100% !important; + -webkit-border-radius: 100% !important; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); } + +.fdb-block { + font-family: 'Roboto', sans-serif; + font-size: 16px; + line-height: 1.5; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-rendering: optimizelegibility; + padding: 100px 0; + color: #444444; + position: relative; + background-size: cover; + background-position: center; + overflow: hidden; + background-color: #FFFFFF; } + .fdb-block.fdb-viewport { + min-height: calc(100% - 2 * 100px); } + .fdb-block.fdb-viewport .container { + min-height: calc(100% - 2 * 100px); } + .fdb-block.fdb-image-bg { + color: #f2f2f2; } + .fdb-block .fdb-box { + background: #FFFFFF; + color: #444444; + padding: 60px 40px; + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + overflow: hidden; } + .fdb-block .fdb-touch { + border-top: solid 5px #528bff; } + .fdb-block h1, .fdb-block .text-h1 { + font-size: 2.75rem; + margin-bottom: .5em; + margin-top: .3em; + font-weight: 400; } + .fdb-block h2, .fdb-block .text-h2 { + font-size: 2rem; + margin-bottom: .5em; + margin-top: .3em; + font-weight: 400; } + .fdb-block h3, .fdb-block .text-h3 { + font-size: 1.125rem; + margin-bottom: .5em; + margin-top: .3em; + font-weight: 400; } + .fdb-block h4, .fdb-block .text-h4 { + font-size: 1rem; + margin-bottom: .5em; + margin-top: .3em; + font-weight: 400; } + .fdb-block h5, .fdb-block .text-h5 { + font-size: 0.9rem; + margin-bottom: .5em; + margin-top: .3em; + font-weight: 400; } + .fdb-block h6, .fdb-block .text-h6 { + font-size: 0.75rem; + margin-bottom: .5em; + margin-top: .3em; + font-weight: 400; } + .fdb-block .font-weight-light { + font-weight: 300; } + .fdb-block img { + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; } + .fdb-block img + p, .fdb-block img + h3, .fdb-block img + h4 { + margin-top: 20px; } + .fdb-block img + h1, .fdb-block img + h2 { + margin-top: 40px; } + .fdb-block .col-fill-left { + width: 50%; + position: absolute; + left: 0; + top: 0; + bottom: 0; + background-size: cover; + background-position: center; + z-index: 1; } + .fdb-block .col-fill-left + div { + position: relative; + z-index: 2; } + .fdb-block .col-fill-right { + width: 50%; + position: absolute; + right: 0; + top: 0; + bottom: 0; + background-size: cover; + background-position: center; + z-index: 1; } + .fdb-block .col-fill-right + div { + position: relative; + z-index: 2; } + .fdb-block img.fdb-icon { + width: auto; + width: 60px; } + .fdb-block img.fdb-icon-round { + width: auto; + width: 60px; + border-radius: 60px; + -moz-border-radius: 60px; + -webkit-border-radius: 60px; } + .fdb-block .row-100 { + height: 100px; + width: 100%; } + .fdb-block .row-50 { + height: 50px; + width: 100%; } + .fdb-block .row-70 { + height: 70px; + width: 100%; } + +footer { + padding: 30px 0 !important; } + footer.footer-large { + padding: 100px 0 !important; } + footer .flex-column .nav-link { + padding-left: 0; } + footer.bg-dark { + background: #2d313c; + color: #f2f2f2; } + footer.bg-dark a { + color: #f2f2f2; } + footer a { + color: #444444; } + +header { + background-color: #FFFFFF; } + header .navbar-nav a.nav-link { + color: #777; } + header .navbar-nav a.nav-link:hover { + color: #528bff; } + header .navbar-nav .active a.nav-link { + color: #444444; } + header .navbar-toggler-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"); } + header.bg-dark .navbar-nav a.nav-link { + color: #dcdcdc; } + header.bg-dark .navbar-nav a.nav-link:hover { + color: #528bff; } + header.bg-dark .navbar-nav .active a.nav-link { + color: #FFFFFF; } + header.bg-dark .navbar-toggler-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#fff' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 8h24M4 16h24M4 24h24'/%3E%3C/svg%3E"); } + +header + header { + border-top: solid 1px #EEE; } + +.bg-dark { + background-color: #2d313c; + color: #f2f2f2; } + +.bg-gray { + background-color: #fafafa; + color: #444444; } + +.br { + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + overflow: hidden; } + +.br-0 { + border-radius: 0 !important; + -moz-border-radius: 0 !important; + -webkit-border-radius: 0 !important; } + +.heart { + color: #df584e; + font-weight: bold; } + +*.text-light { + font-weight: 300 !important; } + +.sl-1 { + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + z-index: 2; } + +table tr.no-border th, table tr.no-border td { + border-top: 0; } diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index acfdfb07..00000000 --- a/debian/changelog +++ /dev/null @@ -1,6 +0,0 @@ -vnote (1.8-0ubuntu1) zesty; urgency=medium - - * Initial release - * Adjusted the Makefile to fix $(DESTDIR) problems. - - -- Le Tan Sun, 20 Aug 2017 09:32:22 +0800 diff --git a/debian/compat b/debian/compat deleted file mode 100644 index ec635144..00000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -9 diff --git a/debian/control b/debian/control deleted file mode 100644 index 33e9e6c1..00000000 --- a/debian/control +++ /dev/null @@ -1,17 +0,0 @@ -Source: vnote -Section: editors -Priority: optional -Maintainer: Le Tan -Build-Depends: debhelper (>=9), qt5-default (>= 5.7.1), libqt5svg5-dev, qtwebengine5-dev, libqt5webchannel5-dev, qtpositioning5-dev -Standards-Version: 3.9.6 -Homepage: https://tamlok.github.io/vnote -Vcs-Browser: https://github.com/tamlok/vnote.git - -Package: vnote -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, libQt5WebEngineWidgets (>= 5.7.1), libQt5WebEngineCore, libQt5PrintSupport, libQt5Widgets, libQt5Gui, libQt5WebChannel, libQt5Network, libQt5Core -Suggests: libssl -Description: A Vim-inspired note-taking application for Markdown. - VNote is a cross-platform, free note-taking application, designed especially - for Markdown. VNote provides both simple note management and pleasant Markdown - edit experience. diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index 73f90572..00000000 --- a/debian/copyright +++ /dev/null @@ -1,7 +0,0 @@ -Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: vnote -Source: https://tamlok.github.io/vnote - -Files: * -Copyright: 2017 Le Tan -License: MIT License diff --git a/debian/rules b/debian/rules deleted file mode 100755 index fcd3d026..00000000 --- a/debian/rules +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/make -f -# See debhelper(7) (uncomment to enable) -# output every command that modifies files on the build system. -#export DH_VERBOSE = 1 - - -# see FEATURE AREAS in dpkg-buildflags(1) -#export DEB_BUILD_MAINT_OPTIONS = hardening=+all - -# see ENVIRONMENT in dpkg-buildflags(1) -# package maintainers to append CFLAGS -#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic -# package maintainers to append LDFLAGS -#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed - - -%: - dh $@ - - -# dh_make generated override targets -# This is example for Cmake (See https://bugs.debian.org/641051 ) -#override_dh_auto_configure: -# dh_auto_configure -- # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) -override_dh_shlibdeps: - dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info - -export QT_SELECT=qt5 diff --git a/debian/source/format b/debian/source/format deleted file mode 100644 index 163aaf8d..00000000 --- a/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/hoedown b/hoedown deleted file mode 160000 index e63d2160..00000000 --- a/hoedown +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e63d2160a7d9895defc253d933b58a83ac54f81a diff --git a/imgs/alt_wide_1.svg b/imgs/alt_wide_1.svg new file mode 100644 index 00000000..8dcd3a11 --- /dev/null +++ b/imgs/alt_wide_1.svg @@ -0,0 +1,1797 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/imgs/concentration.svg b/imgs/concentration.svg new file mode 100644 index 00000000..9c95a820 --- /dev/null +++ b/imgs/concentration.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/imgs/cross_platform.svg b/imgs/cross_platform.svg new file mode 100644 index 00000000..aef1922b --- /dev/null +++ b/imgs/cross_platform.svg @@ -0,0 +1,119 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/imgs/for_programmers.svg b/imgs/for_programmers.svg new file mode 100644 index 00000000..a00339bb --- /dev/null +++ b/imgs/for_programmers.svg @@ -0,0 +1,123 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/imgs/highly_customizable.svg b/imgs/highly_customizable.svg new file mode 100644 index 00000000..3c922513 --- /dev/null +++ b/imgs/highly_customizable.svg @@ -0,0 +1,11475 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/imgs/img_attachment.svg b/imgs/img_attachment.svg new file mode 100644 index 00000000..9fb898bf --- /dev/null +++ b/imgs/img_attachment.svg @@ -0,0 +1,50 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/imgs/img_codeblock.svg b/imgs/img_codeblock.svg new file mode 100644 index 00000000..5b76e609 --- /dev/null +++ b/imgs/img_codeblock.svg @@ -0,0 +1,54 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/imgs/img_expect_more.svg b/imgs/img_expect_more.svg new file mode 100644 index 00000000..33c349b3 --- /dev/null +++ b/imgs/img_expect_more.svg @@ -0,0 +1,47 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/imgs/img_extension.svg b/imgs/img_extension.svg new file mode 100644 index 00000000..c038c074 --- /dev/null +++ b/imgs/img_extension.svg @@ -0,0 +1,51 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/imgs/img_image.svg b/imgs/img_image.svg new file mode 100644 index 00000000..1c3b07b6 --- /dev/null +++ b/imgs/img_image.svg @@ -0,0 +1,56 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/imgs/img_logo.png b/imgs/img_logo.png new file mode 100644 index 00000000..e1515780 Binary files /dev/null and b/imgs/img_logo.png differ diff --git a/imgs/img_outline.svg b/imgs/img_outline.svg new file mode 100644 index 00000000..b4b69949 --- /dev/null +++ b/imgs/img_outline.svg @@ -0,0 +1,90 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/imgs/own_your_data.svg b/imgs/own_your_data.svg new file mode 100644 index 00000000..873ce4e7 --- /dev/null +++ b/imgs/own_your_data.svg @@ -0,0 +1,110 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/imgs/pleasant_markdown_experience.svg b/imgs/pleasant_markdown_experience.svg new file mode 100644 index 00000000..20bbb22d --- /dev/null +++ b/imgs/pleasant_markdown_experience.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/imgs/simple_management.svg b/imgs/simple_management.svg new file mode 100644 index 00000000..3a873840 --- /dev/null +++ b/imgs/simple_management.svg @@ -0,0 +1,107 @@ + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/index.html b/index.html new file mode 100644 index 00000000..548c4684 --- /dev/null +++ b/index.html @@ -0,0 +1,319 @@ + + + + VNote + + + + + + + + + + + + +
+
+ +
+
+ +
+
+
+
+ image +

VNote

+

A note-taking application with Markdown, which knows programmers and Markdown better.

+

+ Github Project + Download +

+
+
+
+
+ +
+
+
+
+ image +
+
+

Concentration

+

Markdown does NOT need live preview side by side. Focus on your note in both read and edit mode.

+
+
+
+
+ +
+
+
+
+

Cross-Platform

+

Built with C++ and Qt, VNote works in major desktop platforms.

+
+ +
+ image +
+
+
+
+ +
+
+
+
+ image +
+
+

Simple Management

+
    +
  • All plain text, no database
  • +
  • One directory to hold one notebook
  • +
  • One notebook contains infinite-level folders
  • +
  • Folders hold your notes
  • +
+
+
+
+
+ +
+
+
+
+

Own Your Data

+

All files on your local disk. Utilize third-party synchronization services to work from anywhere seamlessly.

+
+ +
+ image +
+
+
+
+ +
+
+
+
+ image +
+
+

Pleasant Markdown Experience

+

Minimize the gap between reading and writing Markdown.

+
    +
  • Tuned and meaningful syntax highlights for Markdown
  • +
  • In-place image links preview
  • +
  • Copy/paste images without messy stuff
  • +
  • Syntax highlights for code blocks in edit mode
  • +
  • Interactive outline
  • +
+
+
+
+
+ +
+
+
+
+

Highly Customizable

+

Themes, styles, behaviors. All could be tuned to your taste.

+
+ +
+ image +
+
+
+
+ +
+
+
+
+ image +
+
+

By Programmers, For Programmers

+

Utilize the power of code editors for Markdown notes.

+
    +
  • Vim mode
  • +
  • Line number
  • +
  • Multiple tabs
  • +
  • Split window
  • +
  • Powerful shortcuts
  • +
+
+
+
+
+ +
+
+
+
+

Features

+
+
+
+
+
+
+ image +
+
+

Easy Images

+

Insert images directly from clipboard. Preview images in place in edit mode.

+
+
+
+ +
+
+
+ image +
+
+

Code Blocks

+

Syntax highlights for Code Blocks in both edit and read mode.

+
+
+
+ +
+
+
+ image +
+
+

Interactive Outline

+

Interactive outline in both edit and read mode.

+
+
+
+
+ +
+
+
+
+ image +
+
+

Extensions

+

Mermaid, Flowchart.js, and MathJax.

+
+
+
+ +
+
+
+ image +
+
+

Attachments

+

Link all related files to the notes by attachments.

+
+
+
+ +
+
+
+ image +
+
+

We Could Expect More

+

VNote is in active development. Post your issues or pull requests to shape VNote.

+
+
+
+
+
+
+ +
+
+
+
+

About VNote

+ +
+ +
+

About Me

+ +
+
+
+ + + + + + diff --git a/peg-highlight/peg-highlight.pro b/peg-highlight/peg-highlight.pro deleted file mode 100644 index a7672ba4..00000000 --- a/peg-highlight/peg-highlight.pro +++ /dev/null @@ -1,18 +0,0 @@ -# PEG-Markdown-Highlight -# Github: https://github.com/ali-rantakari/peg-markdown-highlight - -QT -= core gui - -TARGET = peg-highlight - -TEMPLATE = lib - -CONFIG += warn_off -CONFIG += staticlib - -SOURCES += pmh_parser.c \ - pmh_styleparser.c - -HEADERS += pmh_parser.h \ - pmh_styleparser.h \ - pmh_definitions.h diff --git a/peg-highlight/pmh_definitions.h b/peg-highlight/pmh_definitions.h deleted file mode 100755 index 29e7b449..00000000 --- a/peg-highlight/pmh_definitions.h +++ /dev/null @@ -1,125 +0,0 @@ -/* PEG Markdown Highlight - * Copyright 2011-2016 Ali Rantakari -- http://hasseg.org - * Licensed under the GPL2+ and MIT licenses (see LICENSE for more info). - * - * pmh_definitions.h - */ - -#ifndef pmh_MARKDOWN_DEFINITIONS -#define pmh_MARKDOWN_DEFINITIONS - -/** \file -* \brief Global definitions for the parser. -*/ - - -/** -* \brief Element types. -* -* The first (documented) ones are language element types. -* -* The last (non-documented) ones are utility types used -* by the parser itself. -* -* \sa pmh_element -*/ -typedef enum -{ - pmh_LINK, /**< Explicit link */ - pmh_AUTO_LINK_URL, /**< Implicit URL link */ - pmh_AUTO_LINK_EMAIL, /**< Implicit email link */ - pmh_IMAGE, /**< Image definition */ - pmh_CODE, /**< Code (inline) */ - pmh_HTML, /**< HTML */ - pmh_HTML_ENTITY, /**< HTML special entity definition */ - pmh_EMPH, /**< Emphasized text */ - pmh_STRONG, /**< Strong text */ - pmh_LIST_BULLET, /**< Bullet for an unordered list item */ - pmh_LIST_ENUMERATOR, /**< Enumerator for an ordered list item */ - pmh_COMMENT, /**< (HTML) Comment */ - - // Code assumes that pmh_H1-6 are in order. - pmh_H1, /**< Header, level 1 */ - pmh_H2, /**< Header, level 2 */ - pmh_H3, /**< Header, level 3 */ - pmh_H4, /**< Header, level 4 */ - pmh_H5, /**< Header, level 5 */ - pmh_H6, /**< Header, level 6 */ - - pmh_BLOCKQUOTE, /**< Blockquote */ - pmh_VERBATIM, /**< Verbatim (e.g. block of code) */ - pmh_HTMLBLOCK, /**< Block of HTML */ - pmh_HRULE, /**< Horizontal rule */ - pmh_REFERENCE, /**< Reference */ - pmh_NOTE, /**< Note */ - pmh_STRIKE, /**< Strike-through */ - - // Utility types used by the parser itself: - - // List of pmh_RAW element lists, each to be processed separately from - // others (for each element in linked lists of this type, `children` points - // to a linked list of pmh_RAW elements): - pmh_RAW_LIST, /**< Internal to parser. Please ignore. */ - - // Span marker for positions in original input to be post-processed - // in a second parsing step: - pmh_RAW, /**< Internal to parser. Please ignore. */ - - // Additional text to be parsed along with spans in the original input - // (these may be added to linked lists of pmh_RAW elements): - pmh_EXTRA_TEXT, /**< Internal to parser. Please ignore. */ - - // Separates linked lists of pmh_RAW elements into parts to be processed - // separate from each other: - pmh_SEPARATOR, /**< Internal to parser. Please ignore. */ - - // Placeholder element used while parsing: - pmh_NO_TYPE, /**< Internal to parser. Please ignore. */ - - // Linked list of *all* elements created while parsing: - pmh_ALL /**< Internal to parser. Please ignore. */ -} pmh_element_type; - -/** -* \brief Number of types in pmh_element_type. -* \sa pmh_element_type -*/ -#define pmh_NUM_TYPES 31 - -/** -* \brief Number of *language element* types in pmh_element_type. -* \sa pmh_element_type -*/ -#define pmh_NUM_LANG_TYPES (pmh_NUM_TYPES - 6) - - -/** -* \brief A Language element occurrence. -*/ -struct pmh_Element -{ - pmh_element_type type; /**< \brief Type of element */ - unsigned long pos; /**< \brief Unicode code point offset marking the - beginning of this element in the - input. */ - unsigned long end; /**< \brief Unicode code point offset marking the - end of this element in the input. */ - struct pmh_Element *next; /**< \brief Next element in list */ - char *label; /**< \brief Label (for links and references) */ - char *address; /**< \brief Address (for links and references) */ -}; -typedef struct pmh_Element pmh_element; - -/** -* \brief Bitfield enumeration of supported Markdown extensions. -*/ -enum pmh_extensions -{ - pmh_EXT_NONE = 0, /**< No extensions */ - pmh_EXT_NOTES = (1 << 0), /**< Footnote syntax: - http://pandoc.org/README.html#footnotes */ - pmh_EXT_STRIKE = (1 << 1) /**< Strike-through syntax: - http://pandoc.org/README.html#strikeout */ -}; - -#endif diff --git a/peg-highlight/pmh_parser.c b/peg-highlight/pmh_parser.c deleted file mode 100644 index 433e7bfd..00000000 --- a/peg-highlight/pmh_parser.c +++ /dev/null @@ -1,6555 +0,0 @@ -/* A recursive-descent parser generated by greg 0.4.3 */ - -#include -#include -#include -struct _GREG; -#define YYRULECOUNT 225 - -/* PEG Markdown Highlight - * Copyright 2011-2016 Ali Rantakari -- http://hasseg.org - * Licensed under the GPL2+ and MIT licenses (see LICENSE for more info). - * - * pmh_grammar.leg - * - * This is a slightly adapted version of the PEG grammar from John MacFarlane's - * peg-markdown compiler. - */ - -/* PEG Markdown Highlight - * Copyright 2011-2016 Ali Rantakari -- http://hasseg.org - * Licensed under the GPL2+ and MIT licenses (see LICENSE for more info). - * - * pmh_parser_head.c - * - * Code to be inserted into the beginning of the parser code generated - * from the PEG grammar. - */ - -#include "pmh_parser.h" - -#ifndef pmh_DEBUG_OUTPUT -#define pmh_DEBUG_OUTPUT 0 -#endif - -#if pmh_DEBUG_OUTPUT -#define pmh_IF(x) if (x) -#define pmh_PRINTF(x, ...) fprintf(stderr, x, ##__VA_ARGS__) -#define pmh_PUTCHAR(x) putchar(x) -#else -#define pmh_IF(x) -#define pmh_PRINTF(x, ...) -#define pmh_PUTCHAR(x) -#endif - - - -// Alias strdup to _strdup on MSVC: -#ifdef _MSC_VER -#define strdup _strdup -#endif - - -char *strdup_or_null(char *s) -{ - return (s == NULL) ? NULL : strdup(s); -} - - -// Internal language element occurrence structure, containing -// both public and private members: -struct pmh_RealElement -{ - // "Public" members: - // (these must match what's defined in pmh_definitions.h) - // ----------------------------------------------- - pmh_element_type type; - unsigned long pos; - unsigned long end; - struct pmh_RealElement *next; - char *label; - char *address; - - // "Private" members for use by the parser itself: - // ----------------------------------------------- - - // next element in list of all elements: - struct pmh_RealElement *all_elems_next; - - // offset to text (for elements of type pmh_EXTRA_TEXT, used when the - // parser reads the value of 'text'): - int text_offset; - - // text content (for elements of type pmh_EXTRA_TEXT): - char *text; - - // children of element (for elements of type pmh_RAW_LIST) - struct pmh_RealElement *children; -}; -typedef struct pmh_RealElement pmh_realelement; - - - - -// Parser state data: -typedef struct -{ - /* The original, unmodified UTF-8 input: */ - char *original_input; - - /* The offsets of the bytes we have stripped from original_input: */ - unsigned long *strip_positions; - size_t strip_positions_len; - - /* Buffer of characters to be parsed: */ - char *charbuf; - - /* Linked list of {start, end} offset pairs determining which parts */ - /* of charbuf to actually parse: */ - pmh_realelement *current_elem; - pmh_realelement *elem_head; - - /* Current parsing offset within charbuf: */ - unsigned long offset; - - /* The extensions to use for parsing (bitfield */ - /* of enum pmh_extensions): */ - int extensions; - - /* Array of parsing result elements, indexed by type: */ - pmh_realelement **head_elems; - - /* Whether we are parsing only references: */ - bool parsing_only_references; - - /* List of reference elements: */ - pmh_realelement *references; -} parser_data; - -static parser_data *mk_parser_data(char *original_input, - unsigned long *strip_positions, - size_t strip_positions_len, - char *charbuf, - pmh_realelement *parsing_elems, - unsigned long offset, - int extensions, - pmh_realelement **head_elems, - pmh_realelement *references) -{ - parser_data *p_data = (parser_data *)malloc(sizeof(parser_data)); - p_data->extensions = extensions; - p_data->original_input = original_input; - p_data->strip_positions = strip_positions; - p_data->strip_positions_len = strip_positions_len; - p_data->charbuf = charbuf; - p_data->offset = offset; - p_data->elem_head = p_data->current_elem = parsing_elems; - p_data->references = references; - p_data->parsing_only_references = false; - if (head_elems != NULL) - p_data->head_elems = head_elems; - else { - p_data->head_elems = (pmh_realelement **) - malloc(sizeof(pmh_realelement *) * pmh_NUM_TYPES); - int i; - for (i = 0; i < pmh_NUM_TYPES; i++) - p_data->head_elems[i] = NULL; - } - return p_data; -} - - -// Forward declarations -static void parse_markdown(parser_data *p_data); -static void parse_references(parser_data *p_data); - - - - - -static char **get_element_type_names() -{ - static char **elem_type_names = NULL; - if (elem_type_names == NULL) - { - elem_type_names = (char **)malloc(sizeof(char*) * pmh_NUM_LANG_TYPES); - int i; - for (i = 0; i < pmh_NUM_LANG_TYPES; i++) - elem_type_names[i] = NULL; - elem_type_names[pmh_LINK] = "LINK"; - elem_type_names[pmh_AUTO_LINK_URL] = "AUTO_LINK_URL"; - elem_type_names[pmh_AUTO_LINK_EMAIL] = "AUTO_LINK_EMAIL"; - elem_type_names[pmh_IMAGE] = "IMAGE"; - elem_type_names[pmh_CODE] = "CODE"; - elem_type_names[pmh_HTML] = "HTML"; - elem_type_names[pmh_HTML_ENTITY] = "HTML_ENTITY"; - elem_type_names[pmh_EMPH] = "EMPH"; - elem_type_names[pmh_STRONG] = "STRONG"; - elem_type_names[pmh_LIST_BULLET] = "LIST_BULLET"; - elem_type_names[pmh_LIST_ENUMERATOR] = "LIST_ENUMERATOR"; - elem_type_names[pmh_COMMENT] = "COMMENT"; - elem_type_names[pmh_H1] = "H1"; - elem_type_names[pmh_H2] = "H2"; - elem_type_names[pmh_H3] = "H3"; - elem_type_names[pmh_H4] = "H4"; - elem_type_names[pmh_H5] = "H5"; - elem_type_names[pmh_H6] = "H6"; - elem_type_names[pmh_BLOCKQUOTE] = "BLOCKQUOTE"; - elem_type_names[pmh_VERBATIM] = "VERBATIM"; - elem_type_names[pmh_HTMLBLOCK] = "HTMLBLOCK"; - elem_type_names[pmh_HRULE] = "HRULE"; - elem_type_names[pmh_REFERENCE] = "REFERENCE"; - elem_type_names[pmh_NOTE] = "NOTE"; - elem_type_names[pmh_STRIKE] = "STRIKE"; - } - return elem_type_names; -} - -pmh_element_type pmh_element_type_from_name(char *name) -{ - char **elem_type_names = get_element_type_names(); - - int i; - for (i = 0; i < pmh_NUM_LANG_TYPES; i++) - { - char *i_name = elem_type_names[i]; - if (i_name == NULL) - continue; - if (strcmp(i_name, name) == 0) - return i; - } - - return pmh_NO_TYPE; -} - -char *pmh_element_name_from_type(pmh_element_type type) -{ - char **elem_type_names = get_element_type_names(); - char* ret = elem_type_names[type]; - if (ret == NULL) - return "unknown type"; - return ret; -} - - - - -/* -Remove pmh_RAW elements with zero length; return pointer -to new head. -*/ -static pmh_realelement *remove_zero_length_raw_spans(pmh_realelement *elem) -{ - pmh_realelement *head = elem; - pmh_realelement *parent = NULL; - pmh_realelement *c = head; - while (c != NULL) - { - if (c->type == pmh_RAW && c->pos >= c->end) - { - if (parent != NULL) - parent->next = c->next; - else - head = c->next; - parent = c; - c = c->next; - continue; - } - parent = c; - c = c->next; - } - return head; -} - -#if pmh_DEBUG_OUTPUT -/* -Print null-terminated string s.t. some characters are -represented by their corresponding espace sequences -*/ -static void print_str_literal_escapes(char *str) -{ - char *c = str; - pmh_PRINTF("'"); - while (*c != '\0') - { - if (*c == '\n') pmh_PRINTF("\\n"); - else if (*c == '\t') pmh_PRINTF("\\t"); - else putchar(*c); - c++; - } - pmh_PRINTF("'"); -} -#endif - -#if pmh_DEBUG_OUTPUT -/* -Print elements in a linked list of -pmh_RAW, pmh_SEPARATOR, pmh_EXTRA_TEXT elements -*/ -static void print_raw_spans_inline(pmh_realelement *elem) -{ - pmh_realelement *cur = elem; - while (cur != NULL) - { - if (cur->type == pmh_SEPARATOR) - pmh_PRINTF(" ", cur->pos); - else if (cur->type == pmh_EXTRA_TEXT) { - pmh_PRINTF("{pmh_ETEXT "); - print_str_literal_escapes(cur->text); - pmh_PRINTF("}"); - } - else - pmh_PRINTF("(%ld-%ld) ", cur->pos, cur->end); - cur = cur->next; - } -} -#endif - -/* -Perform postprocessing parsing runs for pmh_RAW_LIST elements in `elem`, -iteratively until no such elements exist. -*/ -static void process_raw_blocks(parser_data *p_data) -{ - pmh_PRINTF("--------process_raw_blocks---------\n"); - while (p_data->head_elems[pmh_RAW_LIST] != NULL) - { - pmh_PRINTF("new iteration.\n"); - pmh_realelement *cursor = p_data->head_elems[pmh_RAW_LIST]; - p_data->head_elems[pmh_RAW_LIST] = NULL; - while (cursor != NULL) - { - pmh_realelement *span_list = (pmh_realelement*)cursor->children; - - span_list = remove_zero_length_raw_spans(span_list); - - #if pmh_DEBUG_OUTPUT - pmh_PRINTF(" process: "); - print_raw_spans_inline(span_list); - pmh_PRINTF("\n"); - #endif - - while (span_list != NULL) - { - pmh_PRINTF("next: span_list: %ld-%ld\n", - span_list->pos, span_list->end); - - // Skip separators in the beginning, as well as - // separators after another separator: - if (span_list->type == pmh_SEPARATOR) { - span_list = span_list->next; - continue; - } - - // Store list of spans until next separator in subspan_list: - pmh_realelement *subspan_list = span_list; - pmh_realelement *previous = NULL; - while (span_list != NULL && span_list->type != pmh_SEPARATOR) { - previous = span_list; - span_list = span_list->next; - } - if (span_list != NULL && span_list->type == pmh_SEPARATOR) { - span_list = span_list->next; - previous->next = NULL; - } - - #if pmh_DEBUG_OUTPUT - pmh_PRINTF(" subspan process: "); - print_raw_spans_inline(subspan_list); - pmh_PRINTF("\n"); - #endif - - // Process subspan_list: - parser_data *raw_p_data = mk_parser_data( - p_data->original_input, - p_data->strip_positions, - p_data->strip_positions_len, - p_data->charbuf, - subspan_list, - subspan_list->pos, - p_data->extensions, - p_data->head_elems, - p_data->references - ); - parse_markdown(raw_p_data); - free(raw_p_data); - - pmh_PRINTF("parse over\n"); - } - - cursor = cursor->next; - } - } -} - - -#if pmh_DEBUG_OUTPUT -static void print_raw_blocks(char *text, pmh_realelement *elem[]) -{ - pmh_PRINTF("--------print_raw_blocks---------\n"); - pmh_PRINTF("block:\n"); - pmh_realelement *cursor = elem[pmh_RAW_LIST]; - while (cursor != NULL) - { - print_raw_spans_inline(cursor->children); - cursor = cursor->next; - } -} -#endif - - - - -/* Free all elements created while parsing */ -void pmh_free_elements(pmh_element **elems) -{ - pmh_realelement *cursor = (pmh_realelement*)elems[pmh_ALL]; - while (cursor != NULL) { - pmh_realelement *tofree = cursor; - cursor = cursor->all_elems_next; - if (tofree->text != NULL) - free(tofree->text); - if (tofree->label != NULL) - free(tofree->label); - if (tofree->address != NULL) - free(tofree->address); - free(tofree); - } - elems[pmh_ALL] = NULL; - - free(elems); -} - - - - - - -#define IS_CONTINUATION_BYTE(x) ((x & 0xC0) == 0x80) -#define HAS_UTF8_BOM(x) ( ((*x & 0xFF) == 0xEF)\ - && ((*(x+1) & 0xFF) == 0xBB)\ - && ((*(x+2) & 0xFF) == 0xBF) ) -#define ADD_STRIP_POS(x) \ - /* reallocate more space for the array, if needed: */ \ - if (strip_positions_size <= strip_positions_pos) { \ - size_t new_size = strip_positions_size * 2; \ - unsigned long *new_arr = (unsigned long *) \ - calloc(new_size, \ - sizeof(unsigned long)); \ - memcpy(new_arr, strip_positions, \ - (sizeof(unsigned long) * strip_positions_size)); \ - strip_positions_size = new_size; \ - free(strip_positions); \ - strip_positions = new_arr; \ - } \ - strip_positions[strip_positions_pos] = x; \ - strip_positions_pos++; - -/* -Copy `str` to `out`, while doing the following: - - remove UTF-8 continuation bytes - - remove possible UTF-8 BOM (byte order mark) - - append two newlines to the end (like peg-markdown does) - - keep track of which bytes we have stripped (in strip_positions) -*/ -static int strcpy_preformat(char *str, char **out, - unsigned long **out_strip_positions, - size_t *out_strip_positions_len) -{ - size_t strip_positions_size = 1024; - size_t strip_positions_pos = 0; - unsigned long *strip_positions = (unsigned long *) - calloc(strip_positions_size, - sizeof(unsigned long)); - - - // +2 in the following is due to the "\n\n" suffix: - char *new_str = (char *)malloc(sizeof(char) * strlen(str) + 1 + 2); - char *c = str; - int i = 0; - - if (HAS_UTF8_BOM(c)) { - c += 3; - ADD_STRIP_POS(0); - ADD_STRIP_POS(1); - ADD_STRIP_POS(2); - } - - while (*c != '\0') - { - if (!IS_CONTINUATION_BYTE(*c)) { - *(new_str+i) = *c, i++; - } else { - ADD_STRIP_POS((int)(c-str)); - } - c++; - } - - *(new_str+(i++)) = '\n'; - *(new_str+(i++)) = '\n'; - *(new_str+i) = '\0'; - - *out = new_str; - *out_strip_positions = strip_positions; - *out_strip_positions_len = strip_positions_pos; - return i; -} - - - -void pmh_markdown_to_elements(char *text, int extensions, - pmh_element **out_result[]) -{ - char *text_copy = NULL; - unsigned long *strip_positions = NULL; - size_t strip_positions_len = 0; - int text_copy_len = strcpy_preformat(text, &text_copy, &strip_positions, - &strip_positions_len); - - pmh_realelement *parsing_elem = (pmh_realelement *) - malloc(sizeof(pmh_realelement)); - parsing_elem->type = pmh_RAW; - parsing_elem->pos = 0; - parsing_elem->end = text_copy_len; - parsing_elem->next = NULL; - - parser_data *p_data = mk_parser_data( - text, - strip_positions, - strip_positions_len, - text_copy, - parsing_elem, - 0, - extensions, - NULL, - NULL - ); - pmh_realelement **result = p_data->head_elems; - - if (*text_copy != '\0') - { - // Get reference definitions into p_data->references - parse_references(p_data); - - // Reset parser state to beginning of input - p_data->offset = 0; - p_data->current_elem = p_data->elem_head; - - // Parse whole document - parse_markdown(p_data); - - #if pmh_DEBUG_OUTPUT - print_raw_blocks(text_copy, result); - #endif - - process_raw_blocks(p_data); - } - - free(strip_positions); - free(p_data); - free(parsing_elem); - free(text_copy); - - *out_result = (pmh_element**)result; -} - - - -/* -Mergesort linked list of elements (using comparison function `compare`), -return new head. (Adapted slightly from Simon Tatham's algorithm.) -*/ -static pmh_element *ll_mergesort(pmh_element *list, - int (*compare)(const pmh_element*, - const pmh_element*)) -{ - pmh_element *out_head = NULL; - - if (!list) - return NULL; - - out_head = list; - - /* Merge widths of doubling size until done */ - int merge_width = 1; - while (1) - { - pmh_element *l, *r; /* left & right segment pointers */ - pmh_element *tail = NULL; /* tail of sorted section */ - - l = out_head; - out_head = NULL; - - int merge_count = 0; - - while (l) - { - merge_count++; - - /* Position r, determine lsize & rsize */ - r = l; - int lsize = 0; - int i; - for (i = 0; i < merge_width; i++) { - lsize++; - r = r->next; - if (!r) - break; - } - int rsize = merge_width; - - /* Merge l & r */ - while (lsize > 0 || (rsize > 0 && r)) - { - pmh_element *e = NULL; - bool get_from_left = false; - if (lsize == 0) get_from_left = false; - else if (rsize == 0 || !r) get_from_left = true; - else if (compare(l,r) <= 0) get_from_left = true; - - if (get_from_left) { - e = l; l = l->next; lsize--; - } else { - e = r; r = r->next; rsize--; - } - - /* add the next pmh_element to the merged list */ - if (tail) - tail->next = e; - else - out_head = e; - tail = e; - } - - l = r; - } - tail->next = NULL; - - if (merge_count <= 1) - return out_head; - - merge_width *= 2; - } -} - -static int elem_compare_by_pos(const pmh_element *a, const pmh_element *b) -{ - return a->pos - b->pos; -} - -void pmh_sort_elements_by_pos(pmh_element *element_lists[]) -{ - int i; - for (i = 0; i < pmh_NUM_LANG_TYPES; i++) - element_lists[i] = ll_mergesort(element_lists[i], &elem_compare_by_pos); -} - - - - - - - - -/* return true if extension is selected */ -static bool extension(parser_data *p_data, int ext) -{ - return ((p_data->extensions & ext) != 0); -} - -/* return reference pmh_realelement for a given label */ -static pmh_realelement *get_reference(parser_data *p_data, char *label) -{ - pmh_realelement *cursor = NULL; - if (!label) - return NULL; - - cursor = p_data->references; - - while (cursor != NULL) - { - if (cursor->label && strcmp(label, cursor->label) == 0) - return cursor; - cursor = cursor->next; - } - return NULL; -} - - -/* cons an element/list onto a list, returning pointer to new head */ -static pmh_realelement *cons(pmh_realelement *elem, pmh_realelement *list) -{ - assert(elem != NULL); - - pmh_realelement *cur = elem; - while (cur->next != NULL) { - cur = cur->next; - } - cur->next = list; - - return elem; -} - - -/* reverse a list, returning pointer to new list */ -static pmh_realelement *reverse(pmh_realelement *list) -{ - pmh_realelement *new_head = NULL; - pmh_realelement *next = NULL; - while (list != NULL) { - next = list->next; - list->next = new_head; - new_head = list; - list = next; - } - return new_head; -} - - - -/* construct pmh_realelement */ -static pmh_realelement *mk_element(parser_data *p_data, pmh_element_type type, - long pos, long end) -{ - pmh_realelement *result = (pmh_realelement *)malloc(sizeof(pmh_realelement)); - memset(result, 0, sizeof(*result)); - result->type = type; - result->pos = pos; - result->end = end; - - pmh_realelement *old_all_elements_head = p_data->head_elems[pmh_ALL]; - p_data->head_elems[pmh_ALL] = result; - result->all_elems_next = old_all_elements_head; - - //pmh_PRINTF(" mk_element: %s [%ld - %ld]\n", pmh_element_name_from_type(type), pos, end); - - return result; -} - -static pmh_realelement *copy_element(parser_data *p_data, pmh_realelement *elem) -{ - pmh_realelement *result = mk_element(p_data, elem->type, elem->pos, elem->end); - result->label = strdup_or_null(elem->label); - result->text = strdup_or_null(elem->text); - result->address = strdup_or_null(elem->address); - return result; -} - -/* construct pmh_EXTRA_TEXT pmh_realelement */ -static pmh_realelement *mk_etext(parser_data *p_data, char *string) -{ - pmh_realelement *result; - assert(string != NULL); - result = mk_element(p_data, pmh_EXTRA_TEXT, 0,0); - result->text = strdup_or_null(string); - return result; -} - - -/* -Given an element where the offsets {pos, end} represent -locations in the *parsed text* (defined by the linked list of pmh_RAW and -pmh_EXTRA_TEXT elements in p_data->current_elem), fix these offsets to represent -corresponding offsets in the parse buffer (p_data->charbuf). Also split -the given pmh_realelement into multiple parts if its offsets span multiple -p_data->current_elem elements. Return the (list of) elements with real offsets. -*/ -static pmh_realelement *fix_offsets(parser_data *p_data, pmh_realelement *elem) -{ - pmh_realelement *new_head = NULL; - if (elem->type == pmh_EXTRA_TEXT) - return mk_etext(p_data, elem->text); - - new_head = copy_element(p_data, elem); - - pmh_realelement *tail = new_head; - pmh_realelement *prev = NULL; - - bool found_start = false; - bool found_end = false; - bool tail_needs_pos = false; - unsigned long previous_end = 0; - unsigned long c = 0; - - pmh_realelement *cursor = p_data->elem_head; - while (cursor != NULL) - { - int thislen = (cursor->type == pmh_EXTRA_TEXT) - ? strlen(cursor->text) - : cursor->end - cursor->pos; - - if (tail_needs_pos && cursor->type != pmh_EXTRA_TEXT) { - tail->pos = cursor->pos; - tail_needs_pos = false; - } - - unsigned int this_pos = cursor->pos; - - if (!found_start && (c <= elem->pos && elem->pos <= c+thislen)) { - tail->pos = (cursor->type == pmh_EXTRA_TEXT) - ? previous_end - : cursor->pos + (elem->pos - c); - this_pos = tail->pos; - found_start = true; - } - - if (!found_end && (c <= elem->end && elem->end <= c+thislen)) { - tail->end = (cursor->type == pmh_EXTRA_TEXT) - ? previous_end - : cursor->pos + (elem->end - c); - found_end = true; - } - - if (found_start && found_end) - break; - - if (cursor->type != pmh_EXTRA_TEXT) - previous_end = cursor->end; - - if (found_start) { - pmh_realelement *new_elem = copy_element(p_data, tail); - new_elem->pos = this_pos; - new_elem->end = cursor->end; - new_elem->next = tail; - if (prev != NULL) - prev->next = new_elem; - if (new_head == tail) - new_head = new_elem; - prev = new_elem; - tail_needs_pos = true; - } - - c += thislen; - cursor = cursor->next; - } - - return new_head; -} - - - -/* Add an element to p_data->head_elems. */ -static void add(parser_data *p_data, pmh_realelement *elem) -{ - if (elem->type != pmh_RAW_LIST) - { - pmh_PRINTF(" add: %s [%ld - %ld]\n", - pmh_element_name_from_type(elem->type), elem->pos, elem->end); - elem = fix_offsets(p_data, elem); - pmh_PRINTF(" > %s [%ld - %ld]\n", - pmh_element_name_from_type(elem->type), elem->pos, elem->end); - } - else - { - pmh_PRINTF(" add: pmh_RAW_LIST "); - pmh_realelement *cursor = elem->children; - pmh_realelement *previous = NULL; - while (cursor != NULL) - { - pmh_realelement *next = cursor->next; - pmh_PRINTF("(%ld-%ld)>", cursor->pos, cursor->end); - pmh_realelement *new_cursor = fix_offsets(p_data, cursor); - if (previous != NULL) - previous->next = new_cursor; - else - elem->children = new_cursor; - pmh_PRINTF("(%ld-%ld)", new_cursor->pos, new_cursor->end); - while (new_cursor->next != NULL) { - new_cursor = new_cursor->next; - pmh_PRINTF("(%ld-%ld)", new_cursor->pos, new_cursor->end); - } - pmh_PRINTF(" "); - if (next != NULL) - new_cursor->next = next; - previous = new_cursor; - cursor = next; - } - pmh_PRINTF("\n"); - } - - if (p_data->head_elems[elem->type] == NULL) - p_data->head_elems[elem->type] = elem; - else - { - pmh_realelement *last = elem; - while (last->next != NULL) - last = last->next; - last->next = p_data->head_elems[elem->type]; - p_data->head_elems[elem->type] = elem; - } -} - - -// Given a range in the list of spans we use for parsing (pos, end), return -// a copy of the corresponding section in the original input, with all of -// the UTF-8 bytes intact: -static char *copy_input_span(parser_data *p_data, - unsigned long pos, unsigned long end) -{ - if (end <= pos) - return NULL; - - char *ret = NULL; - - // Adjust (pos,end) to match actual indexes in charbuf: - pmh_realelement *dummy = mk_element(p_data, pmh_NO_TYPE, pos, end); - pmh_realelement *fixed_dummies = fix_offsets(p_data, dummy); - pmh_realelement *cursor = fixed_dummies; - while (cursor != NULL) - { - if (cursor->end <= cursor->pos) - { - cursor = cursor->next; - continue; - } - - // Adjust cursor's span to take bytes stripped from the original - // input into account (i.e. match the corresponding span in - // p_data->original_input): - unsigned long adjusted_pos = cursor->pos; - unsigned long adjusted_end = cursor->end; - size_t i; - for (i = 0; i < p_data->strip_positions_len; i++) - { - unsigned long strip_position = p_data->strip_positions[i]; - if (strip_position <= adjusted_pos) - adjusted_pos++; - if (strip_position <= adjusted_end) - adjusted_end++; - else - break; - } - - // Copy span from original input: - size_t adjusted_len = adjusted_end - adjusted_pos; - char *str = (char *)malloc(sizeof(char)*adjusted_len + 1); - *str = '\0'; - strncat(str, (p_data->original_input + adjusted_pos), adjusted_len); - - if (ret == NULL) - ret = str; - else - { - // append str to ret: - char *new_ret = (char *)malloc(sizeof(char) - *(strlen(str) + strlen(ret)) + 1); - *new_ret = '\0'; - strcat(new_ret, ret); - strcat(new_ret, str); - free(ret); - free(str); - ret = new_ret; - } - - cursor = cursor->next; - } - - return ret; -} - - - - - -# define YYSTYPE pmh_realelement * -#ifdef __DEBUG__ -# define YY_DEBUG 1 -#endif - -#define YY_INPUT(buf, result, max_size)\ - yy_input_func(buf, &result, max_size, (parser_data *)G->data) - -static void yy_input_func(char *buf, int *result, int max_size, - parser_data *p_data) -{ - if (p_data->current_elem == NULL) - { - (*result) = 0; - return; - } - - if (p_data->current_elem->type == pmh_EXTRA_TEXT) - { - int yyc; - bool moreToRead = (p_data->current_elem->text - && *(p_data->current_elem->text - + p_data->current_elem->text_offset) != '\0'); - if (moreToRead) - { - yyc = *(p_data->current_elem->text + p_data->current_elem->text_offset++); - pmh_PRINTF("\e[47;30m"); pmh_PUTCHAR(yyc); pmh_PRINTF("\e[0m"); - pmh_IF(yyc == '\n') pmh_PRINTF("\e[47m \e[0m"); - } - else - { - yyc = EOF; - p_data->current_elem = p_data->current_elem->next; - pmh_PRINTF("\e[41m \e[0m"); - if (p_data->current_elem != NULL) - p_data->offset = p_data->current_elem->pos; - } - (*result) = (EOF == yyc) ? 0 : (*(buf) = yyc, 1); - return; - } - - *(buf) = *(p_data->charbuf + p_data->offset); - (*result) = (*buf != '\0'); - p_data->offset++; - - pmh_PRINTF("\e[43;30m"); pmh_PUTCHAR(*buf); pmh_PRINTF("\e[0m"); - pmh_IF(*buf == '\n') pmh_PRINTF("\e[42m \e[0m"); - - if (p_data->offset >= p_data->current_elem->end) - { - p_data->current_elem = p_data->current_elem->next; - pmh_PRINTF("\e[41m \e[0m"); - if (p_data->current_elem != NULL) - p_data->offset = p_data->current_elem->pos; - } -} - - - -#define elem(x) mk_element((parser_data *)G->data, x, thunk->begin, thunk->end) -#define elem_s(x) mk_element((parser_data *)G->data, x, s->pos, thunk->end) -#define mk_sep mk_element((parser_data *)G->data, pmh_SEPARATOR, 0,0) -#define mk_notype mk_element((parser_data *)G->data, pmh_NO_TYPE, 0,0) -#define etext(x) mk_etext((parser_data *)G->data, x) -#define ADD(x) add((parser_data *)G->data, x) -#define EXT(x) extension((parser_data *)G->data, x) -#define REF_EXISTS(x) reference_exists((parser_data *)G->data, x) -#define GET_REF(x) get_reference((parser_data *)G->data, x) -#define PARSING_REFERENCES ((parser_data *)G->data)->parsing_only_references -#define FREE_LABEL(l) { free(l->label); l->label = NULL; } -#define FREE_ADDRESS(l) { free(l->address); l->address = NULL; } - -// This gives us the text matched with < > as it appears in the original input: -#define COPY_YYTEXT_ORIG() copy_input_span((parser_data *)G->data, thunk->begin, thunk->end) - - -#ifndef YY_ALLOC -#define YY_ALLOC(N, D) malloc(N) -#endif -#ifndef YY_CALLOC -#define YY_CALLOC(N, S, D) calloc(N, S) -#endif -#ifndef YY_REALLOC -#define YY_REALLOC(B, N, D) realloc(B, N) -#endif -#ifndef YY_FREE -#define YY_FREE free -#endif -#ifndef YY_LOCAL -#define YY_LOCAL(T) static T -#endif -#ifndef YY_ACTION -#define YY_ACTION(T) static T -#endif -#ifndef YY_RULE -#define YY_RULE(T) static T -#endif -#ifndef YY_PARSE -#define YY_PARSE(T) T -#endif -#ifndef YY_NAME -#define YY_NAME(N) yy##N -#endif -#ifndef YY_INPUT -#define YY_INPUT(buf, result, max_size) \ - { \ - int yyc= getchar(); \ - result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \ - yyprintf((stderr, "<%c>", yyc)); \ - } -#endif -#ifndef YY_BEGIN -#define YY_BEGIN ( G->begin= G->pos, 1) -#endif -#ifndef YY_END -#define YY_END ( G->end= G->pos, 1) -#endif -#ifdef YY_DEBUG -# define yyprintf(args) fprintf args -#else -# define yyprintf(args) -#endif -#ifndef YYSTYPE -#define YYSTYPE int -#endif -#ifndef YY_XTYPE -#define YY_XTYPE void * -#endif -#ifndef YY_XVAR -#define YY_XVAR yyxvar -#endif - -#ifndef YY_STACK_SIZE -#define YY_STACK_SIZE 128 -#endif - -#ifndef YY_BUFFER_START_SIZE -#define YY_BUFFER_START_SIZE 1024 -#endif - -#ifndef YY_PART -#define yydata G->data -#define yy G->ss - -struct _yythunk; // forward declaration -typedef void (*yyaction)(struct _GREG *G, char *yytext, int yyleng, struct _yythunk *thunkpos, YY_XTYPE YY_XVAR); -typedef struct _yythunk { int begin, end; yyaction action; struct _yythunk *next; } yythunk; - -typedef struct _GREG { - char *buf; - int buflen; - int offset; - int pos; - int limit; - char *text; - int textlen; - int begin; - int end; - yythunk *thunks; - int thunkslen; - int thunkpos; - YYSTYPE ss; - YYSTYPE *val; - YYSTYPE *vals; - int valslen; - YY_XTYPE data; -} GREG; - -YY_LOCAL(int) yyrefill(GREG *G) -{ - int yyn; - while (G->buflen - G->pos < 512) - { - G->buflen *= 2; - G->buf= (char *)YY_REALLOC(G->buf, G->buflen, G->data); - } - YY_INPUT((G->buf + G->pos), yyn, (G->buflen - G->pos)); - if (!yyn) return 0; - G->limit += yyn; - return 1; -} - -YY_LOCAL(int) yymatchDot(GREG *G) -{ - if (G->pos >= G->limit && !yyrefill(G)) return 0; - ++G->pos; - return 1; -} - -YY_LOCAL(int) yymatchChar(GREG *G, int c) -{ - if (G->pos >= G->limit && !yyrefill(G)) return 0; - if ((unsigned char)G->buf[G->pos] == c) - { - ++G->pos; - yyprintf((stderr, " ok yymatchChar(%c) @ %s\n", c, G->buf+G->pos)); - return 1; - } - yyprintf((stderr, " fail yymatchChar(%c) @ %s\n", c, G->buf+G->pos)); - return 0; -} - -YY_LOCAL(int) yymatchString(GREG *G, char *s) -{ - int yysav= G->pos; - while (*s) - { - if (G->pos >= G->limit && !yyrefill(G)) return 0; - if (G->buf[G->pos] != *s) - { - G->pos= yysav; - return 0; - } - ++s; - ++G->pos; - } - return 1; -} - -YY_LOCAL(int) yymatchClass(GREG *G, unsigned char *bits) -{ - int c; - if (G->pos >= G->limit && !yyrefill(G)) return 0; - c= (unsigned char)G->buf[G->pos]; - if (bits[c >> 3] & (1 << (c & 7))) - { - ++G->pos; - yyprintf((stderr, " ok yymatchClass @ %s\n", G->buf+G->pos)); - return 1; - } - yyprintf((stderr, " fail yymatchClass @ %s\n", G->buf+G->pos)); - return 0; -} - -YY_LOCAL(void) yyDo(GREG *G, yyaction action, int begin, int end) -{ - while (G->thunkpos >= G->thunkslen) - { - G->thunkslen *= 2; - G->thunks= (yythunk *)YY_REALLOC(G->thunks, sizeof(yythunk) * G->thunkslen, G->data); - } - G->thunks[G->thunkpos].begin= begin; - G->thunks[G->thunkpos].end= end; - G->thunks[G->thunkpos].action= action; - ++G->thunkpos; -} - -YY_LOCAL(int) yyText(GREG *G, int begin, int end) -{ - int yyleng= end - begin; - if (yyleng <= 0) - yyleng= 0; - else - { - while (G->textlen < (yyleng + 1)) - { - G->textlen *= 2; - G->text= (char *)YY_REALLOC(G->text, G->textlen, G->data); - } - memcpy(G->text, G->buf + begin, yyleng); - } - G->text[yyleng]= '\0'; - return yyleng; -} - -YY_LOCAL(void) yyDone(GREG *G) -{ - int pos; - for (pos= 0; pos < G->thunkpos; ++pos) - { - yythunk *thunk= &G->thunks[pos]; - int yyleng= thunk->end ? yyText(G, thunk->begin, thunk->end) : thunk->begin; - yyprintf((stderr, "DO [%d] %p %s\n", pos, thunk->action, G->text)); - thunk->action(G, G->text, yyleng, thunk, G->data); - } - G->thunkpos= 0; -} - -YY_LOCAL(void) yyCommit(GREG *G) -{ - if ((G->limit -= G->pos)) - { - memmove(G->buf, G->buf + G->pos, G->limit); - } - G->offset += G->pos; - G->begin -= G->pos; - G->end -= G->pos; - G->pos= G->thunkpos= 0; -} - -YY_LOCAL(int) yyAccept(GREG *G, int tp0) -{ - if (tp0) - { - fprintf(stderr, "accept denied at %d\n", tp0); - return 0; - } - else - { - yyDone(G); - yyCommit(G); - } - return 1; -} - -YY_LOCAL(void) yyPush(GREG *G, char *text, int count, yythunk *thunk, YY_XTYPE YY_XVAR) { G->val += count; } -YY_LOCAL(void) yyPop(GREG *G, char *text, int count, yythunk *thunk, YY_XTYPE YY_XVAR) { G->val -= count; } -YY_LOCAL(void) yySet(GREG *G, char *text, int count, yythunk *thunk, YY_XTYPE YY_XVAR) { G->val[count]= G->ss; } - -#endif /* YY_PART */ - -#define YYACCEPT yyAccept(G, yythunkpos0) - -YY_RULE(int) yy_RawNoteBlock(GREG *G); /* 225 */ -YY_RULE(int) yy_RawNoteReference(GREG *G); /* 224 */ -YY_RULE(int) yy_ExtendedSpecialChar(GREG *G); /* 223 */ -YY_RULE(int) yy_AlphanumericAscii(GREG *G); /* 222 */ -YY_RULE(int) yy_Quoted(GREG *G); /* 221 */ -YY_RULE(int) yy_HtmlTag(GREG *G); /* 220 */ -YY_RULE(int) yy_Ticks5(GREG *G); /* 219 */ -YY_RULE(int) yy_Ticks4(GREG *G); /* 218 */ -YY_RULE(int) yy_Ticks3(GREG *G); /* 217 */ -YY_RULE(int) yy_Ticks2(GREG *G); /* 216 */ -YY_RULE(int) yy_Ticks1(GREG *G); /* 215 */ -YY_RULE(int) yy_SkipBlock(GREG *G); /* 214 */ -YY_RULE(int) yy_References(GREG *G); /* 213 */ -YY_RULE(int) yy_EmptyTitle(GREG *G); /* 212 */ -YY_RULE(int) yy_RefTitleParens(GREG *G); /* 211 */ -YY_RULE(int) yy_RefTitleDouble(GREG *G); /* 210 */ -YY_RULE(int) yy_RefTitleSingle(GREG *G); /* 209 */ -YY_RULE(int) yy_RefTitle(GREG *G); /* 208 */ -YY_RULE(int) yy_RefSrc(GREG *G); /* 207 */ -YY_RULE(int) yy_AutoLinkEmail(GREG *G); /* 206 */ -YY_RULE(int) yy_AutoLinkUrl(GREG *G); /* 205 */ -YY_RULE(int) yy_TitleDouble(GREG *G); /* 204 */ -YY_RULE(int) yy_TitleSingle(GREG *G); /* 203 */ -YY_RULE(int) yy_Nonspacechar(GREG *G); /* 202 */ -YY_RULE(int) yy_SourceContents(GREG *G); /* 201 */ -YY_RULE(int) yy_Title(GREG *G); /* 200 */ -YY_RULE(int) yy_Source(GREG *G); /* 199 */ -YY_RULE(int) yy_Label(GREG *G); /* 198 */ -YY_RULE(int) yy_ReferenceLinkSingle(GREG *G); /* 197 */ -YY_RULE(int) yy_ReferenceLinkDouble(GREG *G); /* 196 */ -YY_RULE(int) yy_AutoLink(GREG *G); /* 195 */ -YY_RULE(int) yy_ReferenceLink(GREG *G); /* 194 */ -YY_RULE(int) yy_ExplicitLink(GREG *G); /* 193 */ -YY_RULE(int) yy_StrongUl(GREG *G); /* 192 */ -YY_RULE(int) yy_StrongStar(GREG *G); /* 191 */ -YY_RULE(int) yy_Whitespace(GREG *G); /* 190 */ -YY_RULE(int) yy_EmphUl(GREG *G); /* 189 */ -YY_RULE(int) yy_EmphStar(GREG *G); /* 188 */ -YY_RULE(int) yy_StarLine(GREG *G); /* 187 */ -YY_RULE(int) yy_UlLine(GREG *G); /* 186 */ -YY_RULE(int) yy_SpecialChar(GREG *G); /* 185 */ -YY_RULE(int) yy_Eof(GREG *G); /* 184 */ -YY_RULE(int) yy_NormalEndline(GREG *G); /* 183 */ -YY_RULE(int) yy_TerminalEndline(GREG *G); /* 182 */ -YY_RULE(int) yy_LineBreak(GREG *G); /* 181 */ -YY_RULE(int) yy_CharEntity(GREG *G); /* 180 */ -YY_RULE(int) yy_DecEntity(GREG *G); /* 179 */ -YY_RULE(int) yy_HexEntity(GREG *G); /* 178 */ -YY_RULE(int) yy_Alphanumeric(GREG *G); /* 177 */ -YY_RULE(int) yy_NormalChar(GREG *G); /* 176 */ -YY_RULE(int) yy_Symbol(GREG *G); /* 175 */ -YY_RULE(int) yy_EscapedChar(GREG *G); /* 174 */ -YY_RULE(int) yy_Entity(GREG *G); /* 173 */ -YY_RULE(int) yy_RawHtml(GREG *G); /* 172 */ -YY_RULE(int) yy_Code(GREG *G); /* 171 */ -YY_RULE(int) yy_InlineNote(GREG *G); /* 170 */ -YY_RULE(int) yy_NoteReference(GREG *G); /* 169 */ -YY_RULE(int) yy_Link(GREG *G); /* 168 */ -YY_RULE(int) yy_Image(GREG *G); /* 167 */ -YY_RULE(int) yy_Strike(GREG *G); /* 166 */ -YY_RULE(int) yy_Emph(GREG *G); /* 165 */ -YY_RULE(int) yy_Strong(GREG *G); /* 164 */ -YY_RULE(int) yy_Space(GREG *G); /* 163 */ -YY_RULE(int) yy_UlOrStarLine(GREG *G); /* 162 */ -YY_RULE(int) yy_Str(GREG *G); /* 161 */ -YY_RULE(int) yy_InStyleTags(GREG *G); /* 160 */ -YY_RULE(int) yy_StyleClose(GREG *G); /* 159 */ -YY_RULE(int) yy_StyleOpen(GREG *G); /* 158 */ -YY_RULE(int) yy_HtmlBlockType(GREG *G); /* 157 */ -YY_RULE(int) yy_HtmlBlockSelfClosing(GREG *G); /* 156 */ -YY_RULE(int) yy_HtmlComment(GREG *G); /* 155 */ -YY_RULE(int) yy_HtmlBlockInTags(GREG *G); /* 154 */ -YY_RULE(int) yy_HtmlBlockHead(GREG *G); /* 153 */ -YY_RULE(int) yy_HtmlBlockCloseHead(GREG *G); /* 152 */ -YY_RULE(int) yy_HtmlBlockOpenHead(GREG *G); /* 151 */ -YY_RULE(int) yy_HtmlBlockScript(GREG *G); /* 150 */ -YY_RULE(int) yy_HtmlBlockCloseScript(GREG *G); /* 149 */ -YY_RULE(int) yy_HtmlBlockOpenScript(GREG *G); /* 148 */ -YY_RULE(int) yy_HtmlBlockTr(GREG *G); /* 147 */ -YY_RULE(int) yy_HtmlBlockCloseTr(GREG *G); /* 146 */ -YY_RULE(int) yy_HtmlBlockOpenTr(GREG *G); /* 145 */ -YY_RULE(int) yy_HtmlBlockThead(GREG *G); /* 144 */ -YY_RULE(int) yy_HtmlBlockCloseThead(GREG *G); /* 143 */ -YY_RULE(int) yy_HtmlBlockOpenThead(GREG *G); /* 142 */ -YY_RULE(int) yy_HtmlBlockTh(GREG *G); /* 141 */ -YY_RULE(int) yy_HtmlBlockCloseTh(GREG *G); /* 140 */ -YY_RULE(int) yy_HtmlBlockOpenTh(GREG *G); /* 139 */ -YY_RULE(int) yy_HtmlBlockTfoot(GREG *G); /* 138 */ -YY_RULE(int) yy_HtmlBlockCloseTfoot(GREG *G); /* 137 */ -YY_RULE(int) yy_HtmlBlockOpenTfoot(GREG *G); /* 136 */ -YY_RULE(int) yy_HtmlBlockTd(GREG *G); /* 135 */ -YY_RULE(int) yy_HtmlBlockCloseTd(GREG *G); /* 134 */ -YY_RULE(int) yy_HtmlBlockOpenTd(GREG *G); /* 133 */ -YY_RULE(int) yy_HtmlBlockTbody(GREG *G); /* 132 */ -YY_RULE(int) yy_HtmlBlockCloseTbody(GREG *G); /* 131 */ -YY_RULE(int) yy_HtmlBlockOpenTbody(GREG *G); /* 130 */ -YY_RULE(int) yy_HtmlBlockLi(GREG *G); /* 129 */ -YY_RULE(int) yy_HtmlBlockCloseLi(GREG *G); /* 128 */ -YY_RULE(int) yy_HtmlBlockOpenLi(GREG *G); /* 127 */ -YY_RULE(int) yy_HtmlBlockFrameset(GREG *G); /* 126 */ -YY_RULE(int) yy_HtmlBlockCloseFrameset(GREG *G); /* 125 */ -YY_RULE(int) yy_HtmlBlockOpenFrameset(GREG *G); /* 124 */ -YY_RULE(int) yy_HtmlBlockDt(GREG *G); /* 123 */ -YY_RULE(int) yy_HtmlBlockCloseDt(GREG *G); /* 122 */ -YY_RULE(int) yy_HtmlBlockOpenDt(GREG *G); /* 121 */ -YY_RULE(int) yy_HtmlBlockDd(GREG *G); /* 120 */ -YY_RULE(int) yy_HtmlBlockCloseDd(GREG *G); /* 119 */ -YY_RULE(int) yy_HtmlBlockOpenDd(GREG *G); /* 118 */ -YY_RULE(int) yy_HtmlBlockUl(GREG *G); /* 117 */ -YY_RULE(int) yy_HtmlBlockCloseUl(GREG *G); /* 116 */ -YY_RULE(int) yy_HtmlBlockOpenUl(GREG *G); /* 115 */ -YY_RULE(int) yy_HtmlBlockTable(GREG *G); /* 114 */ -YY_RULE(int) yy_HtmlBlockCloseTable(GREG *G); /* 113 */ -YY_RULE(int) yy_HtmlBlockOpenTable(GREG *G); /* 112 */ -YY_RULE(int) yy_HtmlBlockPre(GREG *G); /* 111 */ -YY_RULE(int) yy_HtmlBlockClosePre(GREG *G); /* 110 */ -YY_RULE(int) yy_HtmlBlockOpenPre(GREG *G); /* 109 */ -YY_RULE(int) yy_HtmlBlockP(GREG *G); /* 108 */ -YY_RULE(int) yy_HtmlBlockCloseP(GREG *G); /* 107 */ -YY_RULE(int) yy_HtmlBlockOpenP(GREG *G); /* 106 */ -YY_RULE(int) yy_HtmlBlockOl(GREG *G); /* 105 */ -YY_RULE(int) yy_HtmlBlockCloseOl(GREG *G); /* 104 */ -YY_RULE(int) yy_HtmlBlockOpenOl(GREG *G); /* 103 */ -YY_RULE(int) yy_HtmlBlockNoscript(GREG *G); /* 102 */ -YY_RULE(int) yy_HtmlBlockCloseNoscript(GREG *G); /* 101 */ -YY_RULE(int) yy_HtmlBlockOpenNoscript(GREG *G); /* 100 */ -YY_RULE(int) yy_HtmlBlockNoframes(GREG *G); /* 99 */ -YY_RULE(int) yy_HtmlBlockCloseNoframes(GREG *G); /* 98 */ -YY_RULE(int) yy_HtmlBlockOpenNoframes(GREG *G); /* 97 */ -YY_RULE(int) yy_HtmlBlockMenu(GREG *G); /* 96 */ -YY_RULE(int) yy_HtmlBlockCloseMenu(GREG *G); /* 95 */ -YY_RULE(int) yy_HtmlBlockOpenMenu(GREG *G); /* 94 */ -YY_RULE(int) yy_HtmlBlockH6(GREG *G); /* 93 */ -YY_RULE(int) yy_HtmlBlockCloseH6(GREG *G); /* 92 */ -YY_RULE(int) yy_HtmlBlockOpenH6(GREG *G); /* 91 */ -YY_RULE(int) yy_HtmlBlockH5(GREG *G); /* 90 */ -YY_RULE(int) yy_HtmlBlockCloseH5(GREG *G); /* 89 */ -YY_RULE(int) yy_HtmlBlockOpenH5(GREG *G); /* 88 */ -YY_RULE(int) yy_HtmlBlockH4(GREG *G); /* 87 */ -YY_RULE(int) yy_HtmlBlockCloseH4(GREG *G); /* 86 */ -YY_RULE(int) yy_HtmlBlockOpenH4(GREG *G); /* 85 */ -YY_RULE(int) yy_HtmlBlockH3(GREG *G); /* 84 */ -YY_RULE(int) yy_HtmlBlockCloseH3(GREG *G); /* 83 */ -YY_RULE(int) yy_HtmlBlockOpenH3(GREG *G); /* 82 */ -YY_RULE(int) yy_HtmlBlockH2(GREG *G); /* 81 */ -YY_RULE(int) yy_HtmlBlockCloseH2(GREG *G); /* 80 */ -YY_RULE(int) yy_HtmlBlockOpenH2(GREG *G); /* 79 */ -YY_RULE(int) yy_HtmlBlockH1(GREG *G); /* 78 */ -YY_RULE(int) yy_HtmlBlockCloseH1(GREG *G); /* 77 */ -YY_RULE(int) yy_HtmlBlockOpenH1(GREG *G); /* 76 */ -YY_RULE(int) yy_HtmlBlockForm(GREG *G); /* 75 */ -YY_RULE(int) yy_HtmlBlockCloseForm(GREG *G); /* 74 */ -YY_RULE(int) yy_HtmlBlockOpenForm(GREG *G); /* 73 */ -YY_RULE(int) yy_HtmlBlockFieldset(GREG *G); /* 72 */ -YY_RULE(int) yy_HtmlBlockCloseFieldset(GREG *G); /* 71 */ -YY_RULE(int) yy_HtmlBlockOpenFieldset(GREG *G); /* 70 */ -YY_RULE(int) yy_HtmlBlockDl(GREG *G); /* 69 */ -YY_RULE(int) yy_HtmlBlockCloseDl(GREG *G); /* 68 */ -YY_RULE(int) yy_HtmlBlockOpenDl(GREG *G); /* 67 */ -YY_RULE(int) yy_HtmlBlockDiv(GREG *G); /* 66 */ -YY_RULE(int) yy_HtmlBlockCloseDiv(GREG *G); /* 65 */ -YY_RULE(int) yy_HtmlBlockOpenDiv(GREG *G); /* 64 */ -YY_RULE(int) yy_HtmlBlockDir(GREG *G); /* 63 */ -YY_RULE(int) yy_HtmlBlockCloseDir(GREG *G); /* 62 */ -YY_RULE(int) yy_HtmlBlockOpenDir(GREG *G); /* 61 */ -YY_RULE(int) yy_HtmlBlockCenter(GREG *G); /* 60 */ -YY_RULE(int) yy_HtmlBlockCloseCenter(GREG *G); /* 59 */ -YY_RULE(int) yy_HtmlBlockOpenCenter(GREG *G); /* 58 */ -YY_RULE(int) yy_HtmlBlockBlockquote(GREG *G); /* 57 */ -YY_RULE(int) yy_HtmlBlockCloseBlockquote(GREG *G); /* 56 */ -YY_RULE(int) yy_HtmlBlockOpenBlockquote(GREG *G); /* 55 */ -YY_RULE(int) yy_HtmlBlockAddress(GREG *G); /* 54 */ -YY_RULE(int) yy_HtmlBlockCloseAddress(GREG *G); /* 53 */ -YY_RULE(int) yy_HtmlAttribute(GREG *G); /* 52 */ -YY_RULE(int) yy_Spnl(GREG *G); /* 51 */ -YY_RULE(int) yy_HtmlBlockOpenAddress(GREG *G); /* 50 */ -YY_RULE(int) yy_OptionallyIndentedLine(GREG *G); /* 49 */ -YY_RULE(int) yy_Indent(GREG *G); /* 48 */ -YY_RULE(int) yy_ListBlockLine(GREG *G); /* 47 */ -YY_RULE(int) yy_ListContinuationBlock(GREG *G); /* 46 */ -YY_RULE(int) yy_ListBlock(GREG *G); /* 45 */ -YY_RULE(int) yy_ListItem(GREG *G); /* 44 */ -YY_RULE(int) yy_Enumerator(GREG *G); /* 43 */ -YY_RULE(int) yy_ListItemTight(GREG *G); /* 42 */ -YY_RULE(int) yy_ListLoose(GREG *G); /* 41 */ -YY_RULE(int) yy_ListTight(GREG *G); /* 40 */ -YY_RULE(int) yy_Spacechar(GREG *G); /* 39 */ -YY_RULE(int) yy_Bullet(GREG *G); /* 38 */ -YY_RULE(int) yy_VerbatimChunk(GREG *G); /* 37 */ -YY_RULE(int) yy_IndentedLine(GREG *G); /* 36 */ -YY_RULE(int) yy_NonblankIndentedLine(GREG *G); /* 35 */ -YY_RULE(int) yy_Line(GREG *G); /* 34 */ -YY_RULE(int) yy_StartList(GREG *G); /* 33 */ -YY_RULE(int) yy_BlockQuoteRaw(GREG *G); /* 32 */ -YY_RULE(int) yy_Endline(GREG *G); /* 31 */ -YY_RULE(int) yy_RawLine(GREG *G); /* 30 */ -YY_RULE(int) yy_SetextBottom2(GREG *G); /* 29 */ -YY_RULE(int) yy_SetextBottom1(GREG *G); /* 28 */ -YY_RULE(int) yy_SetextHeading2(GREG *G); /* 27 */ -YY_RULE(int) yy_SetextHeading1(GREG *G); /* 26 */ -YY_RULE(int) yy_SetextHeading(GREG *G); /* 25 */ -YY_RULE(int) yy_AtxHeading(GREG *G); /* 24 */ -YY_RULE(int) yy_AtxStart(GREG *G); /* 23 */ -YY_RULE(int) yy_Inline(GREG *G); /* 22 */ -YY_RULE(int) yy_Sp(GREG *G); /* 21 */ -YY_RULE(int) yy_Newline(GREG *G); /* 20 */ -YY_RULE(int) yy_AtxInline(GREG *G); /* 19 */ -YY_RULE(int) yy_Inlines(GREG *G); /* 18 */ -YY_RULE(int) yy_NonindentSpace(GREG *G); /* 17 */ -YY_RULE(int) yy_Plain(GREG *G); /* 16 */ -YY_RULE(int) yy_Para(GREG *G); /* 15 */ -YY_RULE(int) yy_StyleBlock(GREG *G); /* 14 */ -YY_RULE(int) yy_HtmlBlock(GREG *G); /* 13 */ -YY_RULE(int) yy_BulletList(GREG *G); /* 12 */ -YY_RULE(int) yy_OrderedList(GREG *G); /* 11 */ -YY_RULE(int) yy_Heading(GREG *G); /* 10 */ -YY_RULE(int) yy_HorizontalRule(GREG *G); /* 9 */ -YY_RULE(int) yy_Reference(GREG *G); /* 8 */ -YY_RULE(int) yy_Note(GREG *G); /* 7 */ -YY_RULE(int) yy_Verbatim(GREG *G); /* 6 */ -YY_RULE(int) yy_BlockQuote(GREG *G); /* 5 */ -YY_RULE(int) yy_BlankLine(GREG *G); /* 4 */ -YY_RULE(int) yy_LocMarker(GREG *G); /* 3 */ -YY_RULE(int) yy_Block(GREG *G); /* 2 */ -YY_RULE(int) yy_Doc(GREG *G); /* 1 */ - -YY_ACTION(void) yy_1_RawLine(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_RawLine\n")); - yy = elem(pmh_RAW); ; -} -YY_ACTION(void) yy_1_Line(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Line\n")); - yy = mk_element((parser_data *)G->data, pmh_RAW, yy->pos, yy->end); ; -} -YY_ACTION(void) yy_1_StartList(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_StartList\n")); - yy = NULL; ; -} -YY_ACTION(void) yy_1_HtmlComment(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_HtmlComment\n")); - ADD(elem_s(pmh_COMMENT)); ; -#undef s -} -YY_ACTION(void) yy_1_RawHtml(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_RawHtml\n")); - ADD(elem_s(pmh_HTML)); ; -#undef s -} -YY_ACTION(void) yy_1_Code(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_Code\n")); - ADD(elem_s(pmh_CODE)); ; -#undef s -} -YY_ACTION(void) yy_1_Ticks5(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Ticks5\n")); - yy = elem(pmh_NO_TYPE); ; -} -YY_ACTION(void) yy_1_Ticks4(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Ticks4\n")); - yy = elem(pmh_NO_TYPE); ; -} -YY_ACTION(void) yy_1_Ticks3(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Ticks3\n")); - yy = elem(pmh_NO_TYPE); ; -} -YY_ACTION(void) yy_1_Ticks2(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Ticks2\n")); - yy = elem(pmh_NO_TYPE); ; -} -YY_ACTION(void) yy_1_Ticks1(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Ticks1\n")); - yy = elem(pmh_NO_TYPE); ; -} -YY_ACTION(void) yy_1_RefSrc(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_RefSrc\n")); - yy = mk_notype; yy->address = COPY_YYTEXT_ORIG(); ; -} -YY_ACTION(void) yy_2_Label(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_2_Label\n")); - - s->pos = s->pos; - s->end = thunk->end; - yy = s; - ; -#undef s -} -YY_ACTION(void) yy_1_Label(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_Label\n")); - s->label = COPY_YYTEXT_ORIG(); ; -#undef s -} -YY_ACTION(void) yy_1_Reference(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define r G->val[-1] -#define l G->val[-2] -#define s G->val[-3] - yyprintf((stderr, "do yy_1_Reference\n")); - - pmh_realelement *el = elem_s(pmh_REFERENCE); - el->label = strdup_or_null(l->label); - el->address = strdup_or_null(r->address); - ADD(el); - FREE_LABEL(l); - FREE_ADDRESS(r); - ; -#undef r -#undef l -#undef s -} -YY_ACTION(void) yy_3_AutoLinkEmail(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_3_AutoLinkEmail\n")); - - s->end = thunk->end; - ADD(s); - ; -#undef s -} -YY_ACTION(void) yy_2_AutoLinkEmail(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_2_AutoLinkEmail\n")); - s->address = COPY_YYTEXT_ORIG(); ; -#undef s -} -YY_ACTION(void) yy_1_AutoLinkEmail(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_AutoLinkEmail\n")); - s->type = pmh_AUTO_LINK_EMAIL; ; -#undef s -} -YY_ACTION(void) yy_3_AutoLinkUrl(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_3_AutoLinkUrl\n")); - - s->end = thunk->end; - ADD(s); - ; -#undef s -} -YY_ACTION(void) yy_2_AutoLinkUrl(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_2_AutoLinkUrl\n")); - s->address = COPY_YYTEXT_ORIG(); ; -#undef s -} -YY_ACTION(void) yy_1_AutoLinkUrl(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_AutoLinkUrl\n")); - s->type = pmh_AUTO_LINK_URL; ; -#undef s -} -YY_ACTION(void) yy_3_Source(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_3_Source\n")); - yy->address = COPY_YYTEXT_ORIG(); ; -} -YY_ACTION(void) yy_2_Source(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_2_Source\n")); - yy->address = COPY_YYTEXT_ORIG(); ; -} -YY_ACTION(void) yy_1_Source(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Source\n")); - yy = mk_notype; ; -} -YY_ACTION(void) yy_1_ExplicitLink(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define l G->val[-1] -#define s G->val[-2] - yyprintf((stderr, "do yy_1_ExplicitLink\n")); - - yy = elem_s(pmh_LINK); - if (l->address != NULL) - yy->address = strdup_or_null(l->address); - FREE_LABEL(s); - FREE_ADDRESS(l); - ; -#undef l -#undef s -} -YY_ACTION(void) yy_1_ReferenceLinkSingle(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_ReferenceLinkSingle\n")); - - pmh_realelement *reference = GET_REF(s->label); - if (reference) { - yy = elem_s(pmh_LINK); - yy->label = strdup_or_null(s->label); - yy->address = strdup_or_null(reference->address); - } else - yy = NULL; - FREE_LABEL(s); - ; -#undef s -} -YY_ACTION(void) yy_1_ReferenceLinkDouble(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define l G->val[-1] -#define s G->val[-2] - yyprintf((stderr, "do yy_1_ReferenceLinkDouble\n")); - - pmh_realelement *reference = GET_REF(l->label); - if (reference) { - yy = elem_s(pmh_LINK); - yy->label = strdup_or_null(l->label); - yy->address = strdup_or_null(reference->address); - } else - yy = NULL; - FREE_LABEL(s); - FREE_LABEL(l); - ; -#undef l -#undef s -} -YY_ACTION(void) yy_1_Link(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Link\n")); - if (yy) ADD(yy); ; -} -YY_ACTION(void) yy_1_Image(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Image\n")); - - if (yy != NULL) { - yy->type = pmh_IMAGE; - yy->pos -= 1; - ADD(yy); - } - ; -} -YY_ACTION(void) yy_1_Strike(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_Strike\n")); - ADD(elem_s(pmh_STRIKE)); ; -#undef s -} -YY_ACTION(void) yy_1_StrongUl(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_StrongUl\n")); - ADD(elem_s(pmh_STRONG)); ; -#undef s -} -YY_ACTION(void) yy_1_StrongStar(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_StrongStar\n")); - ADD(elem_s(pmh_STRONG)); ; -#undef s -} -YY_ACTION(void) yy_1_EmphUl(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_EmphUl\n")); - ADD(elem_s(pmh_EMPH)); ; -#undef s -} -YY_ACTION(void) yy_1_EmphStar(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_EmphStar\n")); - ADD(elem_s(pmh_EMPH)); ; -#undef s -} -YY_ACTION(void) yy_1_Entity(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_Entity\n")); - ADD(elem_s(pmh_HTML_ENTITY)); ; -#undef s -} -YY_ACTION(void) yy_1_StyleBlock(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_StyleBlock\n")); - ADD(elem_s(pmh_HTMLBLOCK)); ; -#undef s -} -YY_ACTION(void) yy_1_HtmlBlock(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_HtmlBlock\n")); - ADD(elem_s(pmh_HTMLBLOCK)); ; -#undef s -} -YY_ACTION(void) yy_1_HtmlBlockH6(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_HtmlBlockH6\n")); - ADD(elem_s(pmh_H6)); ; -#undef s -} -YY_ACTION(void) yy_1_HtmlBlockH5(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_HtmlBlockH5\n")); - ADD(elem_s(pmh_H5)); ; -#undef s -} -YY_ACTION(void) yy_1_HtmlBlockH4(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_HtmlBlockH4\n")); - ADD(elem_s(pmh_H4)); ; -#undef s -} -YY_ACTION(void) yy_1_HtmlBlockH3(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_HtmlBlockH3\n")); - ADD(elem_s(pmh_H3)); ; -#undef s -} -YY_ACTION(void) yy_1_HtmlBlockH2(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_HtmlBlockH2\n")); - ADD(elem_s(pmh_H2)); ; -#undef s -} -YY_ACTION(void) yy_1_HtmlBlockH1(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_HtmlBlockH1\n")); - ADD(elem_s(pmh_H1)); ; -#undef s -} -YY_ACTION(void) yy_1_Enumerator(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Enumerator\n")); - ADD(elem(pmh_LIST_ENUMERATOR)); ; -} -YY_ACTION(void) yy_3_ListContinuationBlock(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_3_ListContinuationBlock\n")); - yy = a; ; -#undef a -} -YY_ACTION(void) yy_2_ListContinuationBlock(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_2_ListContinuationBlock\n")); - a = cons(yy, a); ; -#undef a -} -YY_ACTION(void) yy_1_ListContinuationBlock(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_1_ListContinuationBlock\n")); - if (*yytext == '\0') /* if strlen(yytext) == 0 */ - a = cons(elem(pmh_SEPARATOR), a); - else - a = cons(elem(pmh_RAW), a); - ; -#undef a -} -YY_ACTION(void) yy_3_ListBlock(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_3_ListBlock\n")); - yy = a; ; -#undef a -} -YY_ACTION(void) yy_2_ListBlock(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_2_ListBlock\n")); - a = cons(elem(pmh_RAW), a); ; -#undef a -} -YY_ACTION(void) yy_1_ListBlock(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_1_ListBlock\n")); - a = cons(yy, a); ; -#undef a -} -YY_ACTION(void) yy_3_ListItemTight(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_3_ListItemTight\n")); - yy = a; ; -#undef a -} -YY_ACTION(void) yy_2_ListItemTight(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_2_ListItemTight\n")); - a = cons(yy, a); ; -#undef a -} -YY_ACTION(void) yy_1_ListItemTight(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_1_ListItemTight\n")); - a = cons(yy, a); ; -#undef a -} -YY_ACTION(void) yy_3_ListItem(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_3_ListItem\n")); - yy = a; ; -#undef a -} -YY_ACTION(void) yy_2_ListItem(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_2_ListItem\n")); - a = cons(yy, a); ; -#undef a -} -YY_ACTION(void) yy_1_ListItem(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_1_ListItem\n")); - a = cons(yy, a); ; -#undef a -} -YY_ACTION(void) yy_2_ListLoose(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define b G->val[-1] -#define a G->val[-2] - yyprintf((stderr, "do yy_2_ListLoose\n")); - pmh_realelement *cur = a; - while (cur != NULL) { - pmh_realelement *rawlist = mk_element((parser_data *)G->data, pmh_RAW_LIST, 0,0); - rawlist->children = reverse(cur->children); - ADD(rawlist); - cur = cur->next; - } - ; -#undef b -#undef a -} -YY_ACTION(void) yy_1_ListLoose(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define b G->val[-1] -#define a G->val[-2] - yyprintf((stderr, "do yy_1_ListLoose\n")); - b = cons(etext("\n\n"), b); /* In loose list, \n\n added to end of each element */ - pmh_realelement *el = mk_notype; - el->children = b; - a = cons(el, a); - ; -#undef b -#undef a -} -YY_ACTION(void) yy_2_ListTight(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_2_ListTight\n")); - pmh_realelement *cur = a; - while (cur != NULL) { - pmh_realelement *rawlist = mk_element((parser_data *)G->data, pmh_RAW_LIST, 0,0); - rawlist->children = reverse(cur->children); - ADD(rawlist); - cur = cur->next; - } - ; -#undef a -} -YY_ACTION(void) yy_1_ListTight(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_1_ListTight\n")); - pmh_realelement *el = mk_notype; - el->children = yy; - a = cons(el, a); - ; -#undef a -} -YY_ACTION(void) yy_1_Bullet(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Bullet\n")); - ADD(elem(pmh_LIST_BULLET)); ; -} -YY_ACTION(void) yy_1_HorizontalRule(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_HorizontalRule\n")); - ADD(elem(pmh_HRULE)); ; -} -YY_ACTION(void) yy_1_Verbatim(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_Verbatim\n")); - ADD(elem_s(pmh_VERBATIM)); ; -#undef s -} -YY_ACTION(void) yy_5_BlockQuoteRaw(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_5_BlockQuoteRaw\n")); - yy = a; ; -#undef a -} -YY_ACTION(void) yy_4_BlockQuoteRaw(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_4_BlockQuoteRaw\n")); - a = cons(etext("\n"), a); ; -#undef a -} -YY_ACTION(void) yy_3_BlockQuoteRaw(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_3_BlockQuoteRaw\n")); - a = cons(yy, a); ; -#undef a -} -YY_ACTION(void) yy_2_BlockQuoteRaw(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_2_BlockQuoteRaw\n")); - a = cons(yy, a); ; -#undef a -} -YY_ACTION(void) yy_1_BlockQuoteRaw(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_1_BlockQuoteRaw\n")); - ADD(elem(pmh_BLOCKQUOTE)); ; -#undef a -} -YY_ACTION(void) yy_1_BlockQuote(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_1_BlockQuote\n")); - pmh_realelement *rawlist = mk_element((parser_data *)G->data, pmh_RAW_LIST, 0,0); - rawlist->children = reverse(a); - ADD(rawlist); - ; -#undef a -} -YY_ACTION(void) yy_1_SetextHeading2(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_SetextHeading2\n")); - ADD(elem_s(pmh_H2)); ; -#undef s -} -YY_ACTION(void) yy_1_SetextHeading1(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_SetextHeading1\n")); - ADD(elem_s(pmh_H1)); ; -#undef s -} -YY_ACTION(void) yy_1_AtxHeading(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_AtxHeading\n")); - ADD(elem_s(s->type)); ; -#undef s -} -YY_ACTION(void) yy_1_AtxStart(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_AtxStart\n")); - yy = elem((pmh_element_type)(pmh_H1 + (strlen(yytext) - 1))); ; -} -YY_ACTION(void) yy_1_LocMarker(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_LocMarker\n")); - yy = elem(pmh_NO_TYPE); ; -} - -YY_RULE(int) yy_RawNoteBlock(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "RawNoteBlock")); - { int yypos4= G->pos, yythunkpos4= G->thunkpos; if (!yy_BlankLine(G)) { goto l4; } goto l1; - l4:; G->pos= yypos4; G->thunkpos= yythunkpos4; - } if (!yy_OptionallyIndentedLine(G)) { goto l1; } - l2:; - { int yypos3= G->pos, yythunkpos3= G->thunkpos; - { int yypos5= G->pos, yythunkpos5= G->thunkpos; if (!yy_BlankLine(G)) { goto l5; } goto l3; - l5:; G->pos= yypos5; G->thunkpos= yythunkpos5; - } if (!yy_OptionallyIndentedLine(G)) { goto l3; } goto l2; - l3:; G->pos= yypos3; G->thunkpos= yythunkpos3; - } - l6:; - { int yypos7= G->pos, yythunkpos7= G->thunkpos; if (!yy_BlankLine(G)) { goto l7; } goto l6; - l7:; G->pos= yypos7; G->thunkpos= yythunkpos7; - } - yyprintf((stderr, " ok %s @ %s\n", "RawNoteBlock", G->buf+G->pos)); - return 1; - l1:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RawNoteBlock", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_RawNoteReference(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "RawNoteReference")); if (!yymatchString(G, "[^")) goto l8; - { int yypos11= G->pos, yythunkpos11= G->thunkpos; if (!yy_Newline(G)) { goto l11; } goto l8; - l11:; G->pos= yypos11; G->thunkpos= yythunkpos11; - } - { int yypos12= G->pos, yythunkpos12= G->thunkpos; if (!yymatchChar(G, ']')) goto l12; goto l8; - l12:; G->pos= yypos12; G->thunkpos= yythunkpos12; - } if (!yymatchDot(G)) goto l8; - l9:; - { int yypos10= G->pos, yythunkpos10= G->thunkpos; - { int yypos13= G->pos, yythunkpos13= G->thunkpos; if (!yy_Newline(G)) { goto l13; } goto l10; - l13:; G->pos= yypos13; G->thunkpos= yythunkpos13; - } - { int yypos14= G->pos, yythunkpos14= G->thunkpos; if (!yymatchChar(G, ']')) goto l14; goto l10; - l14:; G->pos= yypos14; G->thunkpos= yythunkpos14; - } if (!yymatchDot(G)) goto l10; goto l9; - l10:; G->pos= yypos10; G->thunkpos= yythunkpos10; - } if (!yymatchChar(G, ']')) goto l8; - yyprintf((stderr, " ok %s @ %s\n", "RawNoteReference", G->buf+G->pos)); - return 1; - l8:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RawNoteReference", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ExtendedSpecialChar(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "ExtendedSpecialChar")); yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_NOTES) )) goto l15; if (!yymatchChar(G, '^')) goto l15; - yyprintf((stderr, " ok %s @ %s\n", "ExtendedSpecialChar", G->buf+G->pos)); - return 1; - l15:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ExtendedSpecialChar", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_AlphanumericAscii(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "AlphanumericAscii")); if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l16; - yyprintf((stderr, " ok %s @ %s\n", "AlphanumericAscii", G->buf+G->pos)); - return 1; - l16:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "AlphanumericAscii", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Quoted(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Quoted")); - { int yypos18= G->pos, yythunkpos18= G->thunkpos; if (!yymatchChar(G, '"')) goto l19; - l20:; - { int yypos21= G->pos, yythunkpos21= G->thunkpos; - { int yypos22= G->pos, yythunkpos22= G->thunkpos; if (!yymatchChar(G, '"')) goto l22; goto l21; - l22:; G->pos= yypos22; G->thunkpos= yythunkpos22; - } if (!yymatchDot(G)) goto l21; goto l20; - l21:; G->pos= yypos21; G->thunkpos= yythunkpos21; - } if (!yymatchChar(G, '"')) goto l19; goto l18; - l19:; G->pos= yypos18; G->thunkpos= yythunkpos18; if (!yymatchChar(G, '\'')) goto l17; - l23:; - { int yypos24= G->pos, yythunkpos24= G->thunkpos; - { int yypos25= G->pos, yythunkpos25= G->thunkpos; if (!yymatchChar(G, '\'')) goto l25; goto l24; - l25:; G->pos= yypos25; G->thunkpos= yythunkpos25; - } if (!yymatchDot(G)) goto l24; goto l23; - l24:; G->pos= yypos24; G->thunkpos= yythunkpos24; - } if (!yymatchChar(G, '\'')) goto l17; - } - l18:; - yyprintf((stderr, " ok %s @ %s\n", "Quoted", G->buf+G->pos)); - return 1; - l17:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Quoted", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlTag(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlTag")); if (!yymatchChar(G, '<')) goto l26; if (!yy_Spnl(G)) { goto l26; } - { int yypos27= G->pos, yythunkpos27= G->thunkpos; if (!yymatchChar(G, '/')) goto l27; goto l28; - l27:; G->pos= yypos27; G->thunkpos= yythunkpos27; - } - l28:; if (!yy_AlphanumericAscii(G)) { goto l26; } - l29:; - { int yypos30= G->pos, yythunkpos30= G->thunkpos; if (!yy_AlphanumericAscii(G)) { goto l30; } goto l29; - l30:; G->pos= yypos30; G->thunkpos= yythunkpos30; - } if (!yy_Spnl(G)) { goto l26; } - l31:; - { int yypos32= G->pos, yythunkpos32= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l32; } goto l31; - l32:; G->pos= yypos32; G->thunkpos= yythunkpos32; - } - { int yypos33= G->pos, yythunkpos33= G->thunkpos; if (!yymatchChar(G, '/')) goto l33; goto l34; - l33:; G->pos= yypos33; G->thunkpos= yythunkpos33; - } - l34:; if (!yy_Spnl(G)) { goto l26; } if (!yymatchChar(G, '>')) goto l26; - yyprintf((stderr, " ok %s @ %s\n", "HtmlTag", G->buf+G->pos)); - return 1; - l26:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlTag", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Ticks5(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Ticks5")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l35; if (!yymatchString(G, "`````")) goto l35; yyText(G, G->begin, G->end); if (!(YY_END)) goto l35; - { int yypos36= G->pos, yythunkpos36= G->thunkpos; if (!yymatchChar(G, '`')) goto l36; goto l35; - l36:; G->pos= yypos36; G->thunkpos= yythunkpos36; - } yyDo(G, yy_1_Ticks5, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Ticks5", G->buf+G->pos)); - return 1; - l35:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Ticks5", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Ticks4(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Ticks4")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l37; if (!yymatchString(G, "````")) goto l37; yyText(G, G->begin, G->end); if (!(YY_END)) goto l37; - { int yypos38= G->pos, yythunkpos38= G->thunkpos; if (!yymatchChar(G, '`')) goto l38; goto l37; - l38:; G->pos= yypos38; G->thunkpos= yythunkpos38; - } yyDo(G, yy_1_Ticks4, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Ticks4", G->buf+G->pos)); - return 1; - l37:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Ticks4", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Ticks3(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Ticks3")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l39; if (!yymatchString(G, "```")) goto l39; yyText(G, G->begin, G->end); if (!(YY_END)) goto l39; - { int yypos40= G->pos, yythunkpos40= G->thunkpos; if (!yymatchChar(G, '`')) goto l40; goto l39; - l40:; G->pos= yypos40; G->thunkpos= yythunkpos40; - } yyDo(G, yy_1_Ticks3, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Ticks3", G->buf+G->pos)); - return 1; - l39:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Ticks3", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Ticks2(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Ticks2")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l41; if (!yymatchString(G, "``")) goto l41; yyText(G, G->begin, G->end); if (!(YY_END)) goto l41; - { int yypos42= G->pos, yythunkpos42= G->thunkpos; if (!yymatchChar(G, '`')) goto l42; goto l41; - l42:; G->pos= yypos42; G->thunkpos= yythunkpos42; - } yyDo(G, yy_1_Ticks2, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Ticks2", G->buf+G->pos)); - return 1; - l41:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Ticks2", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Ticks1(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Ticks1")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l43; if (!yymatchChar(G, '`')) goto l43; yyText(G, G->begin, G->end); if (!(YY_END)) goto l43; - { int yypos44= G->pos, yythunkpos44= G->thunkpos; if (!yymatchChar(G, '`')) goto l44; goto l43; - l44:; G->pos= yypos44; G->thunkpos= yythunkpos44; - } yyDo(G, yy_1_Ticks1, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Ticks1", G->buf+G->pos)); - return 1; - l43:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Ticks1", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_SkipBlock(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "SkipBlock")); - { int yypos46= G->pos, yythunkpos46= G->thunkpos; - { int yypos50= G->pos, yythunkpos50= G->thunkpos; if (!yy_BlankLine(G)) { goto l50; } goto l47; - l50:; G->pos= yypos50; G->thunkpos= yythunkpos50; - } if (!yy_RawLine(G)) { goto l47; } - l48:; - { int yypos49= G->pos, yythunkpos49= G->thunkpos; - { int yypos51= G->pos, yythunkpos51= G->thunkpos; if (!yy_BlankLine(G)) { goto l51; } goto l49; - l51:; G->pos= yypos51; G->thunkpos= yythunkpos51; - } if (!yy_RawLine(G)) { goto l49; } goto l48; - l49:; G->pos= yypos49; G->thunkpos= yythunkpos49; - } - l52:; - { int yypos53= G->pos, yythunkpos53= G->thunkpos; if (!yy_BlankLine(G)) { goto l53; } goto l52; - l53:; G->pos= yypos53; G->thunkpos= yythunkpos53; - } goto l46; - l47:; G->pos= yypos46; G->thunkpos= yythunkpos46; if (!yy_BlankLine(G)) { goto l45; } - l54:; - { int yypos55= G->pos, yythunkpos55= G->thunkpos; if (!yy_BlankLine(G)) { goto l55; } goto l54; - l55:; G->pos= yypos55; G->thunkpos= yythunkpos55; - } - } - l46:; - yyprintf((stderr, " ok %s @ %s\n", "SkipBlock", G->buf+G->pos)); - return 1; - l45:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "SkipBlock", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_References(GREG *G) -{ - yyprintf((stderr, "%s\n", "References")); - l57:; - { int yypos58= G->pos, yythunkpos58= G->thunkpos; - { int yypos59= G->pos, yythunkpos59= G->thunkpos; if (!yy_Reference(G)) { goto l60; } goto l59; - l60:; G->pos= yypos59; G->thunkpos= yythunkpos59; if (!yy_SkipBlock(G)) { goto l58; } - } - l59:; goto l57; - l58:; G->pos= yypos58; G->thunkpos= yythunkpos58; - } - yyprintf((stderr, " ok %s @ %s\n", "References", G->buf+G->pos)); - return 1; -} -YY_RULE(int) yy_EmptyTitle(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "EmptyTitle")); if (!yymatchString(G, "")) goto l61; - yyprintf((stderr, " ok %s @ %s\n", "EmptyTitle", G->buf+G->pos)); - return 1; - l61:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "EmptyTitle", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_RefTitleParens(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "RefTitleParens")); if (!yy_Spnl(G)) { goto l62; } if (!yymatchChar(G, '(')) goto l62; - l63:; - { int yypos64= G->pos, yythunkpos64= G->thunkpos; - { int yypos65= G->pos, yythunkpos65= G->thunkpos; - { int yypos66= G->pos, yythunkpos66= G->thunkpos; if (!yymatchChar(G, ')')) goto l67; if (!yy_Sp(G)) { goto l67; } if (!yy_Newline(G)) { goto l67; } goto l66; - l67:; G->pos= yypos66; G->thunkpos= yythunkpos66; if (!yy_Newline(G)) { goto l65; } - } - l66:; goto l64; - l65:; G->pos= yypos65; G->thunkpos= yythunkpos65; - } if (!yymatchDot(G)) goto l64; goto l63; - l64:; G->pos= yypos64; G->thunkpos= yythunkpos64; - } if (!yymatchChar(G, ')')) goto l62; - yyprintf((stderr, " ok %s @ %s\n", "RefTitleParens", G->buf+G->pos)); - return 1; - l62:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RefTitleParens", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_RefTitleDouble(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "RefTitleDouble")); if (!yy_Spnl(G)) { goto l68; } if (!yymatchChar(G, '"')) goto l68; - l69:; - { int yypos70= G->pos, yythunkpos70= G->thunkpos; - { int yypos71= G->pos, yythunkpos71= G->thunkpos; - { int yypos72= G->pos, yythunkpos72= G->thunkpos; if (!yymatchChar(G, '"')) goto l73; if (!yy_Sp(G)) { goto l73; } if (!yy_Newline(G)) { goto l73; } goto l72; - l73:; G->pos= yypos72; G->thunkpos= yythunkpos72; if (!yy_Newline(G)) { goto l71; } - } - l72:; goto l70; - l71:; G->pos= yypos71; G->thunkpos= yythunkpos71; - } if (!yymatchDot(G)) goto l70; goto l69; - l70:; G->pos= yypos70; G->thunkpos= yythunkpos70; - } if (!yymatchChar(G, '"')) goto l68; - yyprintf((stderr, " ok %s @ %s\n", "RefTitleDouble", G->buf+G->pos)); - return 1; - l68:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RefTitleDouble", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_RefTitleSingle(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "RefTitleSingle")); if (!yy_Spnl(G)) { goto l74; } if (!yymatchChar(G, '\'')) goto l74; - l75:; - { int yypos76= G->pos, yythunkpos76= G->thunkpos; - { int yypos77= G->pos, yythunkpos77= G->thunkpos; - { int yypos78= G->pos, yythunkpos78= G->thunkpos; if (!yymatchChar(G, '\'')) goto l79; if (!yy_Sp(G)) { goto l79; } if (!yy_Newline(G)) { goto l79; } goto l78; - l79:; G->pos= yypos78; G->thunkpos= yythunkpos78; if (!yy_Newline(G)) { goto l77; } - } - l78:; goto l76; - l77:; G->pos= yypos77; G->thunkpos= yythunkpos77; - } if (!yymatchDot(G)) goto l76; goto l75; - l76:; G->pos= yypos76; G->thunkpos= yythunkpos76; - } if (!yymatchChar(G, '\'')) goto l74; - yyprintf((stderr, " ok %s @ %s\n", "RefTitleSingle", G->buf+G->pos)); - return 1; - l74:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RefTitleSingle", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_RefTitle(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "RefTitle")); - { int yypos81= G->pos, yythunkpos81= G->thunkpos; if (!yy_RefTitleSingle(G)) { goto l82; } goto l81; - l82:; G->pos= yypos81; G->thunkpos= yythunkpos81; if (!yy_RefTitleDouble(G)) { goto l83; } goto l81; - l83:; G->pos= yypos81; G->thunkpos= yythunkpos81; if (!yy_RefTitleParens(G)) { goto l84; } goto l81; - l84:; G->pos= yypos81; G->thunkpos= yythunkpos81; if (!yy_EmptyTitle(G)) { goto l80; } - } - l81:; - yyprintf((stderr, " ok %s @ %s\n", "RefTitle", G->buf+G->pos)); - return 1; - l80:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RefTitle", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_RefSrc(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "RefSrc")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l85; if (!yy_Nonspacechar(G)) { goto l85; } - l86:; - { int yypos87= G->pos, yythunkpos87= G->thunkpos; if (!yy_Nonspacechar(G)) { goto l87; } goto l86; - l87:; G->pos= yypos87; G->thunkpos= yythunkpos87; - } yyText(G, G->begin, G->end); if (!(YY_END)) goto l85; yyDo(G, yy_1_RefSrc, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "RefSrc", G->buf+G->pos)); - return 1; - l85:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RefSrc", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_AutoLinkEmail(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "AutoLinkEmail")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l88; if (!yy_LocMarker(G)) { goto l88; } yyDo(G, yySet, -1, 0); yyDo(G, yy_1_AutoLinkEmail, G->begin, G->end); if (!yymatchChar(G, '<')) goto l88; - { int yypos89= G->pos, yythunkpos89= G->thunkpos; if (!yymatchString(G, "mailto:")) goto l89; goto l90; - l89:; G->pos= yypos89; G->thunkpos= yythunkpos89; - } - l90:; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l88; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\062\350\377\003\376\377\377\207\376\377\377\107\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l88; - l91:; - { int yypos92= G->pos, yythunkpos92= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\062\350\377\003\376\377\377\207\376\377\377\107\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l92; goto l91; - l92:; G->pos= yypos92; G->thunkpos= yythunkpos92; - } if (!yymatchChar(G, '@')) goto l88; - { int yypos95= G->pos, yythunkpos95= G->thunkpos; if (!yy_Newline(G)) { goto l95; } goto l88; - l95:; G->pos= yypos95; G->thunkpos= yythunkpos95; - } - { int yypos96= G->pos, yythunkpos96= G->thunkpos; if (!yymatchChar(G, '>')) goto l96; goto l88; - l96:; G->pos= yypos96; G->thunkpos= yythunkpos96; - } if (!yymatchDot(G)) goto l88; - l93:; - { int yypos94= G->pos, yythunkpos94= G->thunkpos; - { int yypos97= G->pos, yythunkpos97= G->thunkpos; if (!yy_Newline(G)) { goto l97; } goto l94; - l97:; G->pos= yypos97; G->thunkpos= yythunkpos97; - } - { int yypos98= G->pos, yythunkpos98= G->thunkpos; if (!yymatchChar(G, '>')) goto l98; goto l94; - l98:; G->pos= yypos98; G->thunkpos= yythunkpos98; - } if (!yymatchDot(G)) goto l94; goto l93; - l94:; G->pos= yypos94; G->thunkpos= yythunkpos94; - } yyText(G, G->begin, G->end); if (!(YY_END)) goto l88; yyDo(G, yy_2_AutoLinkEmail, G->begin, G->end); if (!yymatchChar(G, '>')) goto l88; yyText(G, G->begin, G->end); if (!(YY_END)) goto l88; yyDo(G, yy_3_AutoLinkEmail, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "AutoLinkEmail", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l88:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "AutoLinkEmail", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_AutoLinkUrl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "AutoLinkUrl")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l99; if (!yy_LocMarker(G)) { goto l99; } yyDo(G, yySet, -1, 0); yyDo(G, yy_1_AutoLinkUrl, G->begin, G->end); if (!yymatchChar(G, '<')) goto l99; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l99; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\000\000\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l99; - l100:; - { int yypos101= G->pos, yythunkpos101= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\000\000\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l101; goto l100; - l101:; G->pos= yypos101; G->thunkpos= yythunkpos101; - } if (!yymatchString(G, "://")) goto l99; - { int yypos104= G->pos, yythunkpos104= G->thunkpos; if (!yy_Newline(G)) { goto l104; } goto l99; - l104:; G->pos= yypos104; G->thunkpos= yythunkpos104; - } - { int yypos105= G->pos, yythunkpos105= G->thunkpos; if (!yymatchChar(G, '>')) goto l105; goto l99; - l105:; G->pos= yypos105; G->thunkpos= yythunkpos105; - } if (!yymatchDot(G)) goto l99; - l102:; - { int yypos103= G->pos, yythunkpos103= G->thunkpos; - { int yypos106= G->pos, yythunkpos106= G->thunkpos; if (!yy_Newline(G)) { goto l106; } goto l103; - l106:; G->pos= yypos106; G->thunkpos= yythunkpos106; - } - { int yypos107= G->pos, yythunkpos107= G->thunkpos; if (!yymatchChar(G, '>')) goto l107; goto l103; - l107:; G->pos= yypos107; G->thunkpos= yythunkpos107; - } if (!yymatchDot(G)) goto l103; goto l102; - l103:; G->pos= yypos103; G->thunkpos= yythunkpos103; - } yyText(G, G->begin, G->end); if (!(YY_END)) goto l99; yyDo(G, yy_2_AutoLinkUrl, G->begin, G->end); if (!yymatchChar(G, '>')) goto l99; yyText(G, G->begin, G->end); if (!(YY_END)) goto l99; yyDo(G, yy_3_AutoLinkUrl, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "AutoLinkUrl", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l99:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "AutoLinkUrl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_TitleDouble(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "TitleDouble")); if (!yymatchChar(G, '"')) goto l108; - l109:; - { int yypos110= G->pos, yythunkpos110= G->thunkpos; - { int yypos111= G->pos, yythunkpos111= G->thunkpos; if (!yymatchChar(G, '"')) goto l111; if (!yy_Sp(G)) { goto l111; } - { int yypos112= G->pos, yythunkpos112= G->thunkpos; if (!yymatchChar(G, ')')) goto l113; goto l112; - l113:; G->pos= yypos112; G->thunkpos= yythunkpos112; if (!yy_Newline(G)) { goto l111; } - } - l112:; goto l110; - l111:; G->pos= yypos111; G->thunkpos= yythunkpos111; - } if (!yymatchDot(G)) goto l110; goto l109; - l110:; G->pos= yypos110; G->thunkpos= yythunkpos110; - } if (!yymatchChar(G, '"')) goto l108; - yyprintf((stderr, " ok %s @ %s\n", "TitleDouble", G->buf+G->pos)); - return 1; - l108:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "TitleDouble", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_TitleSingle(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "TitleSingle")); if (!yymatchChar(G, '\'')) goto l114; - l115:; - { int yypos116= G->pos, yythunkpos116= G->thunkpos; - { int yypos117= G->pos, yythunkpos117= G->thunkpos; if (!yymatchChar(G, '\'')) goto l117; if (!yy_Sp(G)) { goto l117; } - { int yypos118= G->pos, yythunkpos118= G->thunkpos; if (!yymatchChar(G, ')')) goto l119; goto l118; - l119:; G->pos= yypos118; G->thunkpos= yythunkpos118; if (!yy_Newline(G)) { goto l117; } - } - l118:; goto l116; - l117:; G->pos= yypos117; G->thunkpos= yythunkpos117; - } if (!yymatchDot(G)) goto l116; goto l115; - l116:; G->pos= yypos116; G->thunkpos= yythunkpos116; - } if (!yymatchChar(G, '\'')) goto l114; - yyprintf((stderr, " ok %s @ %s\n", "TitleSingle", G->buf+G->pos)); - return 1; - l114:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "TitleSingle", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Nonspacechar(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Nonspacechar")); - { int yypos121= G->pos, yythunkpos121= G->thunkpos; if (!yy_Spacechar(G)) { goto l121; } goto l120; - l121:; G->pos= yypos121; G->thunkpos= yythunkpos121; - } - { int yypos122= G->pos, yythunkpos122= G->thunkpos; if (!yy_Newline(G)) { goto l122; } goto l120; - l122:; G->pos= yypos122; G->thunkpos= yythunkpos122; - } if (!yymatchDot(G)) goto l120; - yyprintf((stderr, " ok %s @ %s\n", "Nonspacechar", G->buf+G->pos)); - return 1; - l120:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Nonspacechar", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_SourceContents(GREG *G) -{ - yyprintf((stderr, "%s\n", "SourceContents")); - l124:; - { int yypos125= G->pos, yythunkpos125= G->thunkpos; - { int yypos126= G->pos, yythunkpos126= G->thunkpos; - { int yypos130= G->pos, yythunkpos130= G->thunkpos; if (!yymatchChar(G, '(')) goto l130; goto l127; - l130:; G->pos= yypos130; G->thunkpos= yythunkpos130; - } - { int yypos131= G->pos, yythunkpos131= G->thunkpos; if (!yymatchChar(G, ')')) goto l131; goto l127; - l131:; G->pos= yypos131; G->thunkpos= yythunkpos131; - } - { int yypos132= G->pos, yythunkpos132= G->thunkpos; if (!yymatchChar(G, '>')) goto l132; goto l127; - l132:; G->pos= yypos132; G->thunkpos= yythunkpos132; - } if (!yy_Nonspacechar(G)) { goto l127; } - l128:; - { int yypos129= G->pos, yythunkpos129= G->thunkpos; - { int yypos133= G->pos, yythunkpos133= G->thunkpos; if (!yymatchChar(G, '(')) goto l133; goto l129; - l133:; G->pos= yypos133; G->thunkpos= yythunkpos133; - } - { int yypos134= G->pos, yythunkpos134= G->thunkpos; if (!yymatchChar(G, ')')) goto l134; goto l129; - l134:; G->pos= yypos134; G->thunkpos= yythunkpos134; - } - { int yypos135= G->pos, yythunkpos135= G->thunkpos; if (!yymatchChar(G, '>')) goto l135; goto l129; - l135:; G->pos= yypos135; G->thunkpos= yythunkpos135; - } if (!yy_Nonspacechar(G)) { goto l129; } goto l128; - l129:; G->pos= yypos129; G->thunkpos= yythunkpos129; - } goto l126; - l127:; G->pos= yypos126; G->thunkpos= yythunkpos126; if (!yymatchChar(G, '(')) goto l125; if (!yy_SourceContents(G)) { goto l125; } if (!yymatchChar(G, ')')) goto l125; - } - l126:; goto l124; - l125:; G->pos= yypos125; G->thunkpos= yythunkpos125; - } - yyprintf((stderr, " ok %s @ %s\n", "SourceContents", G->buf+G->pos)); - return 1; -} -YY_RULE(int) yy_Title(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Title")); - { int yypos137= G->pos, yythunkpos137= G->thunkpos; if (!yy_TitleSingle(G)) { goto l138; } goto l137; - l138:; G->pos= yypos137; G->thunkpos= yythunkpos137; if (!yy_TitleDouble(G)) { goto l139; } goto l137; - l139:; G->pos= yypos137; G->thunkpos= yythunkpos137; if (!yymatchString(G, "")) goto l136; - } - l137:; - yyprintf((stderr, " ok %s @ %s\n", "Title", G->buf+G->pos)); - return 1; - l136:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Title", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Source(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Source")); yyDo(G, yy_1_Source, G->begin, G->end); - { int yypos141= G->pos, yythunkpos141= G->thunkpos; if (!yymatchChar(G, '<')) goto l142; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l142; if (!yy_SourceContents(G)) { goto l142; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l142; yyDo(G, yy_2_Source, G->begin, G->end); if (!yymatchChar(G, '>')) goto l142; goto l141; - l142:; G->pos= yypos141; G->thunkpos= yythunkpos141; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l140; if (!yy_SourceContents(G)) { goto l140; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l140; yyDo(G, yy_3_Source, G->begin, G->end); - } - l141:; - yyprintf((stderr, " ok %s @ %s\n", "Source", G->buf+G->pos)); - return 1; - l140:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Source", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Label(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "Label")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l143; if (!yy_LocMarker(G)) { goto l143; } yyDo(G, yySet, -1, 0); if (!yymatchChar(G, '[')) goto l143; - { int yypos144= G->pos, yythunkpos144= G->thunkpos; - { int yypos146= G->pos, yythunkpos146= G->thunkpos; if (!yymatchChar(G, '^')) goto l146; goto l145; - l146:; G->pos= yypos146; G->thunkpos= yythunkpos146; - } yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_NOTES) )) goto l145; goto l144; - l145:; G->pos= yypos144; G->thunkpos= yythunkpos144; - { int yypos147= G->pos, yythunkpos147= G->thunkpos; if (!yymatchDot(G)) goto l143; G->pos= yypos147; G->thunkpos= yythunkpos147; - } yyText(G, G->begin, G->end); if (!( !EXT(pmh_EXT_NOTES) )) goto l143; - } - l144:; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l143; - l148:; - { int yypos149= G->pos, yythunkpos149= G->thunkpos; - { int yypos150= G->pos, yythunkpos150= G->thunkpos; if (!yymatchChar(G, ']')) goto l150; goto l149; - l150:; G->pos= yypos150; G->thunkpos= yythunkpos150; - } if (!yy_Inline(G)) { goto l149; } goto l148; - l149:; G->pos= yypos149; G->thunkpos= yythunkpos149; - } yyText(G, G->begin, G->end); if (!(YY_END)) goto l143; yyDo(G, yy_1_Label, G->begin, G->end); if (!yymatchChar(G, ']')) goto l143; yyText(G, G->begin, G->end); if (!(YY_END)) goto l143; yyDo(G, yy_2_Label, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Label", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l143:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Label", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ReferenceLinkSingle(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "ReferenceLinkSingle")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l151; if (!yy_Label(G)) { goto l151; } yyDo(G, yySet, -1, 0); - { int yypos152= G->pos, yythunkpos152= G->thunkpos; if (!yy_Spnl(G)) { goto l152; } if (!yymatchString(G, "[]")) goto l152; goto l153; - l152:; G->pos= yypos152; G->thunkpos= yythunkpos152; - } - l153:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l151; yyDo(G, yy_1_ReferenceLinkSingle, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ReferenceLinkSingle", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l151:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ReferenceLinkSingle", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ReferenceLinkDouble(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 2, 0); - yyprintf((stderr, "%s\n", "ReferenceLinkDouble")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l154; if (!yy_Label(G)) { goto l154; } yyDo(G, yySet, -2, 0); if (!yy_Spnl(G)) { goto l154; } - { int yypos155= G->pos, yythunkpos155= G->thunkpos; if (!yymatchString(G, "[]")) goto l155; goto l154; - l155:; G->pos= yypos155; G->thunkpos= yythunkpos155; - } if (!yy_Label(G)) { goto l154; } yyDo(G, yySet, -1, 0); yyText(G, G->begin, G->end); if (!(YY_END)) goto l154; yyDo(G, yy_1_ReferenceLinkDouble, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ReferenceLinkDouble", G->buf+G->pos)); yyDo(G, yyPop, 2, 0); - return 1; - l154:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ReferenceLinkDouble", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_AutoLink(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "AutoLink")); - { int yypos157= G->pos, yythunkpos157= G->thunkpos; if (!yy_AutoLinkUrl(G)) { goto l158; } goto l157; - l158:; G->pos= yypos157; G->thunkpos= yythunkpos157; if (!yy_AutoLinkEmail(G)) { goto l156; } - } - l157:; - yyprintf((stderr, " ok %s @ %s\n", "AutoLink", G->buf+G->pos)); - return 1; - l156:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "AutoLink", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ReferenceLink(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "ReferenceLink")); - { int yypos160= G->pos, yythunkpos160= G->thunkpos; if (!yy_ReferenceLinkDouble(G)) { goto l161; } goto l160; - l161:; G->pos= yypos160; G->thunkpos= yythunkpos160; if (!yy_ReferenceLinkSingle(G)) { goto l159; } - } - l160:; - yyprintf((stderr, " ok %s @ %s\n", "ReferenceLink", G->buf+G->pos)); - return 1; - l159:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ReferenceLink", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ExplicitLink(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 2, 0); - yyprintf((stderr, "%s\n", "ExplicitLink")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l162; if (!yy_Label(G)) { goto l162; } yyDo(G, yySet, -2, 0); if (!yy_Spnl(G)) { goto l162; } if (!yymatchChar(G, '(')) goto l162; if (!yy_Sp(G)) { goto l162; } if (!yy_Source(G)) { goto l162; } yyDo(G, yySet, -1, 0); if (!yy_Spnl(G)) { goto l162; } if (!yy_Title(G)) { goto l162; } if (!yy_Sp(G)) { goto l162; } if (!yymatchChar(G, ')')) goto l162; yyText(G, G->begin, G->end); if (!(YY_END)) goto l162; yyDo(G, yy_1_ExplicitLink, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ExplicitLink", G->buf+G->pos)); yyDo(G, yyPop, 2, 0); - return 1; - l162:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ExplicitLink", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_StrongUl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "StrongUl")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l163; if (!yy_LocMarker(G)) { goto l163; } yyDo(G, yySet, -1, 0); if (!yymatchString(G, "__")) goto l163; - { int yypos164= G->pos, yythunkpos164= G->thunkpos; if (!yy_Whitespace(G)) { goto l164; } goto l163; - l164:; G->pos= yypos164; G->thunkpos= yythunkpos164; - } - { int yypos167= G->pos, yythunkpos167= G->thunkpos; if (!yymatchString(G, "__")) goto l167; goto l163; - l167:; G->pos= yypos167; G->thunkpos= yythunkpos167; - } if (!yy_Inline(G)) { goto l163; } - l165:; - { int yypos166= G->pos, yythunkpos166= G->thunkpos; - { int yypos168= G->pos, yythunkpos168= G->thunkpos; if (!yymatchString(G, "__")) goto l168; goto l166; - l168:; G->pos= yypos168; G->thunkpos= yythunkpos168; - } if (!yy_Inline(G)) { goto l166; } goto l165; - l166:; G->pos= yypos166; G->thunkpos= yythunkpos166; - } if (!yymatchString(G, "__")) goto l163; yyText(G, G->begin, G->end); if (!(YY_END)) goto l163; yyDo(G, yy_1_StrongUl, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "StrongUl", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l163:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "StrongUl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_StrongStar(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "StrongStar")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l169; if (!yy_LocMarker(G)) { goto l169; } yyDo(G, yySet, -1, 0); if (!yymatchString(G, "**")) goto l169; - { int yypos170= G->pos, yythunkpos170= G->thunkpos; if (!yy_Whitespace(G)) { goto l170; } goto l169; - l170:; G->pos= yypos170; G->thunkpos= yythunkpos170; - } - { int yypos173= G->pos, yythunkpos173= G->thunkpos; if (!yymatchString(G, "**")) goto l173; goto l169; - l173:; G->pos= yypos173; G->thunkpos= yythunkpos173; - } if (!yy_Inline(G)) { goto l169; } - l171:; - { int yypos172= G->pos, yythunkpos172= G->thunkpos; - { int yypos174= G->pos, yythunkpos174= G->thunkpos; if (!yymatchString(G, "**")) goto l174; goto l172; - l174:; G->pos= yypos174; G->thunkpos= yythunkpos174; - } if (!yy_Inline(G)) { goto l172; } goto l171; - l172:; G->pos= yypos172; G->thunkpos= yythunkpos172; - } if (!yymatchString(G, "**")) goto l169; yyText(G, G->begin, G->end); if (!(YY_END)) goto l169; yyDo(G, yy_1_StrongStar, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "StrongStar", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l169:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "StrongStar", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Whitespace(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Whitespace")); - { int yypos176= G->pos, yythunkpos176= G->thunkpos; if (!yy_Spacechar(G)) { goto l177; } goto l176; - l177:; G->pos= yypos176; G->thunkpos= yythunkpos176; if (!yy_Newline(G)) { goto l175; } - } - l176:; - yyprintf((stderr, " ok %s @ %s\n", "Whitespace", G->buf+G->pos)); - return 1; - l175:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Whitespace", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_EmphUl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "EmphUl")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l178; if (!yy_LocMarker(G)) { goto l178; } yyDo(G, yySet, -1, 0); if (!yymatchChar(G, '_')) goto l178; - { int yypos179= G->pos, yythunkpos179= G->thunkpos; if (!yy_Whitespace(G)) { goto l179; } goto l178; - l179:; G->pos= yypos179; G->thunkpos= yythunkpos179; - } - { int yypos182= G->pos, yythunkpos182= G->thunkpos; - { int yypos184= G->pos, yythunkpos184= G->thunkpos; if (!yymatchChar(G, '_')) goto l184; goto l183; - l184:; G->pos= yypos184; G->thunkpos= yythunkpos184; - } if (!yy_Inline(G)) { goto l183; } goto l182; - l183:; G->pos= yypos182; G->thunkpos= yythunkpos182; if (!yy_StrongUl(G)) { goto l178; } - } - l182:; - l180:; - { int yypos181= G->pos, yythunkpos181= G->thunkpos; - { int yypos185= G->pos, yythunkpos185= G->thunkpos; - { int yypos187= G->pos, yythunkpos187= G->thunkpos; if (!yymatchChar(G, '_')) goto l187; goto l186; - l187:; G->pos= yypos187; G->thunkpos= yythunkpos187; - } if (!yy_Inline(G)) { goto l186; } goto l185; - l186:; G->pos= yypos185; G->thunkpos= yythunkpos185; if (!yy_StrongUl(G)) { goto l181; } - } - l185:; goto l180; - l181:; G->pos= yypos181; G->thunkpos= yythunkpos181; - } if (!yymatchChar(G, '_')) goto l178; yyText(G, G->begin, G->end); if (!(YY_END)) goto l178; yyDo(G, yy_1_EmphUl, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "EmphUl", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l178:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "EmphUl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_EmphStar(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "EmphStar")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l188; if (!yy_LocMarker(G)) { goto l188; } yyDo(G, yySet, -1, 0); if (!yymatchChar(G, '*')) goto l188; - { int yypos189= G->pos, yythunkpos189= G->thunkpos; if (!yy_Whitespace(G)) { goto l189; } goto l188; - l189:; G->pos= yypos189; G->thunkpos= yythunkpos189; - } - { int yypos192= G->pos, yythunkpos192= G->thunkpos; - { int yypos194= G->pos, yythunkpos194= G->thunkpos; if (!yymatchChar(G, '*')) goto l194; goto l193; - l194:; G->pos= yypos194; G->thunkpos= yythunkpos194; - } if (!yy_Inline(G)) { goto l193; } goto l192; - l193:; G->pos= yypos192; G->thunkpos= yythunkpos192; if (!yy_StrongStar(G)) { goto l188; } - } - l192:; - l190:; - { int yypos191= G->pos, yythunkpos191= G->thunkpos; - { int yypos195= G->pos, yythunkpos195= G->thunkpos; - { int yypos197= G->pos, yythunkpos197= G->thunkpos; if (!yymatchChar(G, '*')) goto l197; goto l196; - l197:; G->pos= yypos197; G->thunkpos= yythunkpos197; - } if (!yy_Inline(G)) { goto l196; } goto l195; - l196:; G->pos= yypos195; G->thunkpos= yythunkpos195; if (!yy_StrongStar(G)) { goto l191; } - } - l195:; goto l190; - l191:; G->pos= yypos191; G->thunkpos= yythunkpos191; - } if (!yymatchChar(G, '*')) goto l188; yyText(G, G->begin, G->end); if (!(YY_END)) goto l188; yyDo(G, yy_1_EmphStar, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "EmphStar", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l188:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "EmphStar", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_StarLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "StarLine")); - { int yypos199= G->pos, yythunkpos199= G->thunkpos; if (!yymatchString(G, "****")) goto l200; - l201:; - { int yypos202= G->pos, yythunkpos202= G->thunkpos; if (!yymatchChar(G, '*')) goto l202; goto l201; - l202:; G->pos= yypos202; G->thunkpos= yythunkpos202; - } goto l199; - l200:; G->pos= yypos199; G->thunkpos= yythunkpos199; if (!yy_Spacechar(G)) { goto l198; } if (!yymatchChar(G, '*')) goto l198; - l203:; - { int yypos204= G->pos, yythunkpos204= G->thunkpos; if (!yymatchChar(G, '*')) goto l204; goto l203; - l204:; G->pos= yypos204; G->thunkpos= yythunkpos204; - } - { int yypos205= G->pos, yythunkpos205= G->thunkpos; if (!yy_Spacechar(G)) { goto l198; } G->pos= yypos205; G->thunkpos= yythunkpos205; - } - } - l199:; - yyprintf((stderr, " ok %s @ %s\n", "StarLine", G->buf+G->pos)); - return 1; - l198:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "StarLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_UlLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "UlLine")); - { int yypos207= G->pos, yythunkpos207= G->thunkpos; if (!yymatchString(G, "____")) goto l208; - l209:; - { int yypos210= G->pos, yythunkpos210= G->thunkpos; if (!yymatchChar(G, '_')) goto l210; goto l209; - l210:; G->pos= yypos210; G->thunkpos= yythunkpos210; - } goto l207; - l208:; G->pos= yypos207; G->thunkpos= yythunkpos207; if (!yy_Spacechar(G)) { goto l206; } if (!yymatchChar(G, '_')) goto l206; - l211:; - { int yypos212= G->pos, yythunkpos212= G->thunkpos; if (!yymatchChar(G, '_')) goto l212; goto l211; - l212:; G->pos= yypos212; G->thunkpos= yythunkpos212; - } - { int yypos213= G->pos, yythunkpos213= G->thunkpos; if (!yy_Spacechar(G)) { goto l206; } G->pos= yypos213; G->thunkpos= yythunkpos213; - } - } - l207:; - yyprintf((stderr, " ok %s @ %s\n", "UlLine", G->buf+G->pos)); - return 1; - l206:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "UlLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_SpecialChar(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "SpecialChar")); - { int yypos215= G->pos, yythunkpos215= G->thunkpos; if (!yymatchChar(G, '~')) goto l216; goto l215; - l216:; G->pos= yypos215; G->thunkpos= yythunkpos215; if (!yymatchChar(G, '*')) goto l217; goto l215; - l217:; G->pos= yypos215; G->thunkpos= yythunkpos215; if (!yymatchChar(G, '_')) goto l218; goto l215; - l218:; G->pos= yypos215; G->thunkpos= yythunkpos215; if (!yymatchChar(G, '`')) goto l219; goto l215; - l219:; G->pos= yypos215; G->thunkpos= yythunkpos215; if (!yymatchChar(G, '&')) goto l220; goto l215; - l220:; G->pos= yypos215; G->thunkpos= yythunkpos215; if (!yymatchChar(G, '[')) goto l221; goto l215; - l221:; G->pos= yypos215; G->thunkpos= yythunkpos215; if (!yymatchChar(G, ']')) goto l222; goto l215; - l222:; G->pos= yypos215; G->thunkpos= yythunkpos215; if (!yymatchChar(G, '(')) goto l223; goto l215; - l223:; G->pos= yypos215; G->thunkpos= yythunkpos215; if (!yymatchChar(G, ')')) goto l224; goto l215; - l224:; G->pos= yypos215; G->thunkpos= yythunkpos215; if (!yymatchChar(G, '<')) goto l225; goto l215; - l225:; G->pos= yypos215; G->thunkpos= yythunkpos215; if (!yymatchChar(G, '!')) goto l226; goto l215; - l226:; G->pos= yypos215; G->thunkpos= yythunkpos215; if (!yymatchChar(G, '#')) goto l227; goto l215; - l227:; G->pos= yypos215; G->thunkpos= yythunkpos215; if (!yymatchChar(G, '\\')) goto l228; goto l215; - l228:; G->pos= yypos215; G->thunkpos= yythunkpos215; if (!yymatchChar(G, '\'')) goto l229; goto l215; - l229:; G->pos= yypos215; G->thunkpos= yythunkpos215; if (!yymatchChar(G, '"')) goto l230; goto l215; - l230:; G->pos= yypos215; G->thunkpos= yythunkpos215; if (!yy_ExtendedSpecialChar(G)) { goto l214; } - } - l215:; - yyprintf((stderr, " ok %s @ %s\n", "SpecialChar", G->buf+G->pos)); - return 1; - l214:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "SpecialChar", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Eof(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Eof")); - { int yypos232= G->pos, yythunkpos232= G->thunkpos; if (!yymatchDot(G)) goto l232; goto l231; - l232:; G->pos= yypos232; G->thunkpos= yythunkpos232; - } - yyprintf((stderr, " ok %s @ %s\n", "Eof", G->buf+G->pos)); - return 1; - l231:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Eof", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_NormalEndline(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "NormalEndline")); if (!yy_Sp(G)) { goto l233; } if (!yy_Newline(G)) { goto l233; } - { int yypos234= G->pos, yythunkpos234= G->thunkpos; if (!yy_BlankLine(G)) { goto l234; } goto l233; - l234:; G->pos= yypos234; G->thunkpos= yythunkpos234; - } - { int yypos235= G->pos, yythunkpos235= G->thunkpos; if (!yymatchChar(G, '>')) goto l235; goto l233; - l235:; G->pos= yypos235; G->thunkpos= yythunkpos235; - } - { int yypos236= G->pos, yythunkpos236= G->thunkpos; if (!yy_AtxStart(G)) { goto l236; } goto l233; - l236:; G->pos= yypos236; G->thunkpos= yythunkpos236; - } - { int yypos237= G->pos, yythunkpos237= G->thunkpos; if (!yy_Line(G)) { goto l237; } - { int yypos238= G->pos, yythunkpos238= G->thunkpos; if (!yymatchChar(G, '=')) goto l239; - l240:; - { int yypos241= G->pos, yythunkpos241= G->thunkpos; if (!yymatchChar(G, '=')) goto l241; goto l240; - l241:; G->pos= yypos241; G->thunkpos= yythunkpos241; - } goto l238; - l239:; G->pos= yypos238; G->thunkpos= yythunkpos238; if (!yymatchChar(G, '-')) goto l237; - l242:; - { int yypos243= G->pos, yythunkpos243= G->thunkpos; if (!yymatchChar(G, '-')) goto l243; goto l242; - l243:; G->pos= yypos243; G->thunkpos= yythunkpos243; - } - } - l238:; if (!yy_Newline(G)) { goto l237; } goto l233; - l237:; G->pos= yypos237; G->thunkpos= yythunkpos237; - } - yyprintf((stderr, " ok %s @ %s\n", "NormalEndline", G->buf+G->pos)); - return 1; - l233:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "NormalEndline", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_TerminalEndline(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "TerminalEndline")); if (!yy_Sp(G)) { goto l244; } if (!yy_Newline(G)) { goto l244; } if (!yy_Eof(G)) { goto l244; } - yyprintf((stderr, " ok %s @ %s\n", "TerminalEndline", G->buf+G->pos)); - return 1; - l244:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "TerminalEndline", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_LineBreak(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "LineBreak")); if (!yymatchString(G, " ")) goto l245; if (!yy_NormalEndline(G)) { goto l245; } - yyprintf((stderr, " ok %s @ %s\n", "LineBreak", G->buf+G->pos)); - return 1; - l245:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "LineBreak", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_CharEntity(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "CharEntity")); if (!yymatchChar(G, '&')) goto l246; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l246; - l247:; - { int yypos248= G->pos, yythunkpos248= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l248; goto l247; - l248:; G->pos= yypos248; G->thunkpos= yythunkpos248; - } if (!yymatchChar(G, ';')) goto l246; - yyprintf((stderr, " ok %s @ %s\n", "CharEntity", G->buf+G->pos)); - return 1; - l246:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "CharEntity", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_DecEntity(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "DecEntity")); if (!yymatchChar(G, '&')) goto l249; if (!yymatchChar(G, '#')) goto l249; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l249; - l250:; - { int yypos251= G->pos, yythunkpos251= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l251; goto l250; - l251:; G->pos= yypos251; G->thunkpos= yythunkpos251; - } if (!yymatchChar(G, ';')) goto l249; - yyprintf((stderr, " ok %s @ %s\n", "DecEntity", G->buf+G->pos)); - return 1; - l249:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "DecEntity", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HexEntity(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HexEntity")); if (!yymatchChar(G, '&')) goto l252; if (!yymatchChar(G, '#')) goto l252; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l252; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\176\000\000\000\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l252; - l253:; - { int yypos254= G->pos, yythunkpos254= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\176\000\000\000\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l254; goto l253; - l254:; G->pos= yypos254; G->thunkpos= yythunkpos254; - } if (!yymatchChar(G, ';')) goto l252; - yyprintf((stderr, " ok %s @ %s\n", "HexEntity", G->buf+G->pos)); - return 1; - l252:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HexEntity", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Alphanumeric(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Alphanumeric")); - { int yypos256= G->pos, yythunkpos256= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l257; goto l256; - l257:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\200")) goto l258; goto l256; - l258:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\201")) goto l259; goto l256; - l259:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\202")) goto l260; goto l256; - l260:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\203")) goto l261; goto l256; - l261:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\204")) goto l262; goto l256; - l262:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\205")) goto l263; goto l256; - l263:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\206")) goto l264; goto l256; - l264:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\207")) goto l265; goto l256; - l265:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\210")) goto l266; goto l256; - l266:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\211")) goto l267; goto l256; - l267:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\212")) goto l268; goto l256; - l268:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\213")) goto l269; goto l256; - l269:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\214")) goto l270; goto l256; - l270:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\215")) goto l271; goto l256; - l271:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\216")) goto l272; goto l256; - l272:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\217")) goto l273; goto l256; - l273:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\220")) goto l274; goto l256; - l274:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\221")) goto l275; goto l256; - l275:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\222")) goto l276; goto l256; - l276:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\223")) goto l277; goto l256; - l277:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\224")) goto l278; goto l256; - l278:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\225")) goto l279; goto l256; - l279:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\226")) goto l280; goto l256; - l280:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\227")) goto l281; goto l256; - l281:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\230")) goto l282; goto l256; - l282:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\231")) goto l283; goto l256; - l283:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\232")) goto l284; goto l256; - l284:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\233")) goto l285; goto l256; - l285:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\234")) goto l286; goto l256; - l286:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\235")) goto l287; goto l256; - l287:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\236")) goto l288; goto l256; - l288:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\237")) goto l289; goto l256; - l289:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\240")) goto l290; goto l256; - l290:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\241")) goto l291; goto l256; - l291:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\242")) goto l292; goto l256; - l292:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\243")) goto l293; goto l256; - l293:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\244")) goto l294; goto l256; - l294:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\245")) goto l295; goto l256; - l295:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\246")) goto l296; goto l256; - l296:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\247")) goto l297; goto l256; - l297:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\250")) goto l298; goto l256; - l298:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\251")) goto l299; goto l256; - l299:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\252")) goto l300; goto l256; - l300:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\253")) goto l301; goto l256; - l301:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\254")) goto l302; goto l256; - l302:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\255")) goto l303; goto l256; - l303:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\256")) goto l304; goto l256; - l304:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\257")) goto l305; goto l256; - l305:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\260")) goto l306; goto l256; - l306:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\261")) goto l307; goto l256; - l307:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\262")) goto l308; goto l256; - l308:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\263")) goto l309; goto l256; - l309:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\264")) goto l310; goto l256; - l310:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\265")) goto l311; goto l256; - l311:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\266")) goto l312; goto l256; - l312:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\267")) goto l313; goto l256; - l313:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\270")) goto l314; goto l256; - l314:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\271")) goto l315; goto l256; - l315:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\272")) goto l316; goto l256; - l316:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\273")) goto l317; goto l256; - l317:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\274")) goto l318; goto l256; - l318:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\275")) goto l319; goto l256; - l319:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\276")) goto l320; goto l256; - l320:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\277")) goto l321; goto l256; - l321:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\300")) goto l322; goto l256; - l322:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\301")) goto l323; goto l256; - l323:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\302")) goto l324; goto l256; - l324:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\303")) goto l325; goto l256; - l325:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\304")) goto l326; goto l256; - l326:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\305")) goto l327; goto l256; - l327:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\306")) goto l328; goto l256; - l328:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\307")) goto l329; goto l256; - l329:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\310")) goto l330; goto l256; - l330:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\311")) goto l331; goto l256; - l331:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\312")) goto l332; goto l256; - l332:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\313")) goto l333; goto l256; - l333:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\314")) goto l334; goto l256; - l334:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\315")) goto l335; goto l256; - l335:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\316")) goto l336; goto l256; - l336:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\317")) goto l337; goto l256; - l337:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\320")) goto l338; goto l256; - l338:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\321")) goto l339; goto l256; - l339:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\322")) goto l340; goto l256; - l340:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\323")) goto l341; goto l256; - l341:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\324")) goto l342; goto l256; - l342:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\325")) goto l343; goto l256; - l343:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\326")) goto l344; goto l256; - l344:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\327")) goto l345; goto l256; - l345:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\330")) goto l346; goto l256; - l346:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\331")) goto l347; goto l256; - l347:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\332")) goto l348; goto l256; - l348:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\333")) goto l349; goto l256; - l349:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\334")) goto l350; goto l256; - l350:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\335")) goto l351; goto l256; - l351:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\336")) goto l352; goto l256; - l352:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\337")) goto l353; goto l256; - l353:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\340")) goto l354; goto l256; - l354:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\341")) goto l355; goto l256; - l355:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\342")) goto l356; goto l256; - l356:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\343")) goto l357; goto l256; - l357:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\344")) goto l358; goto l256; - l358:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\345")) goto l359; goto l256; - l359:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\346")) goto l360; goto l256; - l360:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\347")) goto l361; goto l256; - l361:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\350")) goto l362; goto l256; - l362:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\351")) goto l363; goto l256; - l363:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\352")) goto l364; goto l256; - l364:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\353")) goto l365; goto l256; - l365:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\354")) goto l366; goto l256; - l366:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\355")) goto l367; goto l256; - l367:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\356")) goto l368; goto l256; - l368:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\357")) goto l369; goto l256; - l369:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\360")) goto l370; goto l256; - l370:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\361")) goto l371; goto l256; - l371:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\362")) goto l372; goto l256; - l372:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\363")) goto l373; goto l256; - l373:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\364")) goto l374; goto l256; - l374:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\365")) goto l375; goto l256; - l375:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\366")) goto l376; goto l256; - l376:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\367")) goto l377; goto l256; - l377:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\370")) goto l378; goto l256; - l378:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\371")) goto l379; goto l256; - l379:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\372")) goto l380; goto l256; - l380:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\373")) goto l381; goto l256; - l381:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\374")) goto l382; goto l256; - l382:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\375")) goto l383; goto l256; - l383:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\376")) goto l384; goto l256; - l384:; G->pos= yypos256; G->thunkpos= yythunkpos256; if (!yymatchString(G, "\377")) goto l255; - } - l256:; - yyprintf((stderr, " ok %s @ %s\n", "Alphanumeric", G->buf+G->pos)); - return 1; - l255:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Alphanumeric", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_NormalChar(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "NormalChar")); - { int yypos386= G->pos, yythunkpos386= G->thunkpos; - { int yypos387= G->pos, yythunkpos387= G->thunkpos; if (!yy_SpecialChar(G)) { goto l388; } goto l387; - l388:; G->pos= yypos387; G->thunkpos= yythunkpos387; if (!yy_Spacechar(G)) { goto l389; } goto l387; - l389:; G->pos= yypos387; G->thunkpos= yythunkpos387; if (!yy_Newline(G)) { goto l386; } - } - l387:; goto l385; - l386:; G->pos= yypos386; G->thunkpos= yythunkpos386; - } if (!yymatchDot(G)) goto l385; - yyprintf((stderr, " ok %s @ %s\n", "NormalChar", G->buf+G->pos)); - return 1; - l385:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "NormalChar", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Symbol(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Symbol")); if (!yy_SpecialChar(G)) { goto l390; } - yyprintf((stderr, " ok %s @ %s\n", "Symbol", G->buf+G->pos)); - return 1; - l390:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Symbol", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_EscapedChar(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "EscapedChar")); if (!yymatchChar(G, '\\')) goto l391; - { int yypos392= G->pos, yythunkpos392= G->thunkpos; if (!yy_Newline(G)) { goto l392; } goto l391; - l392:; G->pos= yypos392; G->thunkpos= yythunkpos392; - } if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\012\157\000\120\000\000\000\270\001\000\000\070\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l391; - yyprintf((stderr, " ok %s @ %s\n", "EscapedChar", G->buf+G->pos)); - return 1; - l391:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "EscapedChar", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Entity(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "Entity")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l393; if (!yy_LocMarker(G)) { goto l393; } yyDo(G, yySet, -1, 0); - { int yypos394= G->pos, yythunkpos394= G->thunkpos; if (!yy_HexEntity(G)) { goto l395; } goto l394; - l395:; G->pos= yypos394; G->thunkpos= yythunkpos394; if (!yy_DecEntity(G)) { goto l396; } goto l394; - l396:; G->pos= yypos394; G->thunkpos= yythunkpos394; if (!yy_CharEntity(G)) { goto l393; } - } - l394:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l393; yyDo(G, yy_1_Entity, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Entity", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l393:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Entity", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_RawHtml(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "RawHtml")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l397; if (!yy_LocMarker(G)) { goto l397; } yyDo(G, yySet, -1, 0); - { int yypos398= G->pos, yythunkpos398= G->thunkpos; if (!yy_HtmlComment(G)) { goto l399; } goto l398; - l399:; G->pos= yypos398; G->thunkpos= yythunkpos398; if (!yy_HtmlBlockScript(G)) { goto l400; } goto l398; - l400:; G->pos= yypos398; G->thunkpos= yythunkpos398; if (!yy_HtmlTag(G)) { goto l397; } - } - l398:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l397; yyDo(G, yy_1_RawHtml, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "RawHtml", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l397:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RawHtml", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Code(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "Code")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l401; - { int yypos402= G->pos, yythunkpos402= G->thunkpos; if (!yy_Ticks1(G)) { goto l403; } yyDo(G, yySet, -1, 0); if (!yy_Sp(G)) { goto l403; } - { int yypos406= G->pos, yythunkpos406= G->thunkpos; - { int yypos410= G->pos, yythunkpos410= G->thunkpos; if (!yymatchChar(G, '`')) goto l410; goto l407; - l410:; G->pos= yypos410; G->thunkpos= yythunkpos410; - } if (!yy_Nonspacechar(G)) { goto l407; } - l408:; - { int yypos409= G->pos, yythunkpos409= G->thunkpos; - { int yypos411= G->pos, yythunkpos411= G->thunkpos; if (!yymatchChar(G, '`')) goto l411; goto l409; - l411:; G->pos= yypos411; G->thunkpos= yythunkpos411; - } if (!yy_Nonspacechar(G)) { goto l409; } goto l408; - l409:; G->pos= yypos409; G->thunkpos= yythunkpos409; - } goto l406; - l407:; G->pos= yypos406; G->thunkpos= yythunkpos406; - { int yypos413= G->pos, yythunkpos413= G->thunkpos; if (!yy_Ticks1(G)) { goto l413; } goto l412; - l413:; G->pos= yypos413; G->thunkpos= yythunkpos413; - } if (!yymatchChar(G, '`')) goto l412; - l414:; - { int yypos415= G->pos, yythunkpos415= G->thunkpos; if (!yymatchChar(G, '`')) goto l415; goto l414; - l415:; G->pos= yypos415; G->thunkpos= yythunkpos415; - } goto l406; - l412:; G->pos= yypos406; G->thunkpos= yythunkpos406; - { int yypos416= G->pos, yythunkpos416= G->thunkpos; if (!yy_Sp(G)) { goto l416; } if (!yy_Ticks1(G)) { goto l416; } goto l403; - l416:; G->pos= yypos416; G->thunkpos= yythunkpos416; - } - { int yypos417= G->pos, yythunkpos417= G->thunkpos; if (!yy_Spacechar(G)) { goto l418; } goto l417; - l418:; G->pos= yypos417; G->thunkpos= yythunkpos417; if (!yy_Newline(G)) { goto l403; } - { int yypos419= G->pos, yythunkpos419= G->thunkpos; if (!yy_BlankLine(G)) { goto l419; } goto l403; - l419:; G->pos= yypos419; G->thunkpos= yythunkpos419; - } - } - l417:; - } - l406:; - l404:; - { int yypos405= G->pos, yythunkpos405= G->thunkpos; - { int yypos420= G->pos, yythunkpos420= G->thunkpos; - { int yypos424= G->pos, yythunkpos424= G->thunkpos; if (!yymatchChar(G, '`')) goto l424; goto l421; - l424:; G->pos= yypos424; G->thunkpos= yythunkpos424; - } if (!yy_Nonspacechar(G)) { goto l421; } - l422:; - { int yypos423= G->pos, yythunkpos423= G->thunkpos; - { int yypos425= G->pos, yythunkpos425= G->thunkpos; if (!yymatchChar(G, '`')) goto l425; goto l423; - l425:; G->pos= yypos425; G->thunkpos= yythunkpos425; - } if (!yy_Nonspacechar(G)) { goto l423; } goto l422; - l423:; G->pos= yypos423; G->thunkpos= yythunkpos423; - } goto l420; - l421:; G->pos= yypos420; G->thunkpos= yythunkpos420; - { int yypos427= G->pos, yythunkpos427= G->thunkpos; if (!yy_Ticks1(G)) { goto l427; } goto l426; - l427:; G->pos= yypos427; G->thunkpos= yythunkpos427; - } if (!yymatchChar(G, '`')) goto l426; - l428:; - { int yypos429= G->pos, yythunkpos429= G->thunkpos; if (!yymatchChar(G, '`')) goto l429; goto l428; - l429:; G->pos= yypos429; G->thunkpos= yythunkpos429; - } goto l420; - l426:; G->pos= yypos420; G->thunkpos= yythunkpos420; - { int yypos430= G->pos, yythunkpos430= G->thunkpos; if (!yy_Sp(G)) { goto l430; } if (!yy_Ticks1(G)) { goto l430; } goto l405; - l430:; G->pos= yypos430; G->thunkpos= yythunkpos430; - } - { int yypos431= G->pos, yythunkpos431= G->thunkpos; if (!yy_Spacechar(G)) { goto l432; } goto l431; - l432:; G->pos= yypos431; G->thunkpos= yythunkpos431; if (!yy_Newline(G)) { goto l405; } - { int yypos433= G->pos, yythunkpos433= G->thunkpos; if (!yy_BlankLine(G)) { goto l433; } goto l405; - l433:; G->pos= yypos433; G->thunkpos= yythunkpos433; - } - } - l431:; - } - l420:; goto l404; - l405:; G->pos= yypos405; G->thunkpos= yythunkpos405; - } if (!yy_Sp(G)) { goto l403; } if (!yy_Ticks1(G)) { goto l403; } goto l402; - l403:; G->pos= yypos402; G->thunkpos= yythunkpos402; if (!yy_Ticks2(G)) { goto l434; } yyDo(G, yySet, -1, 0); if (!yy_Sp(G)) { goto l434; } - { int yypos437= G->pos, yythunkpos437= G->thunkpos; - { int yypos441= G->pos, yythunkpos441= G->thunkpos; if (!yymatchChar(G, '`')) goto l441; goto l438; - l441:; G->pos= yypos441; G->thunkpos= yythunkpos441; - } if (!yy_Nonspacechar(G)) { goto l438; } - l439:; - { int yypos440= G->pos, yythunkpos440= G->thunkpos; - { int yypos442= G->pos, yythunkpos442= G->thunkpos; if (!yymatchChar(G, '`')) goto l442; goto l440; - l442:; G->pos= yypos442; G->thunkpos= yythunkpos442; - } if (!yy_Nonspacechar(G)) { goto l440; } goto l439; - l440:; G->pos= yypos440; G->thunkpos= yythunkpos440; - } goto l437; - l438:; G->pos= yypos437; G->thunkpos= yythunkpos437; - { int yypos444= G->pos, yythunkpos444= G->thunkpos; if (!yy_Ticks2(G)) { goto l444; } goto l443; - l444:; G->pos= yypos444; G->thunkpos= yythunkpos444; - } if (!yymatchChar(G, '`')) goto l443; - l445:; - { int yypos446= G->pos, yythunkpos446= G->thunkpos; if (!yymatchChar(G, '`')) goto l446; goto l445; - l446:; G->pos= yypos446; G->thunkpos= yythunkpos446; - } goto l437; - l443:; G->pos= yypos437; G->thunkpos= yythunkpos437; - { int yypos447= G->pos, yythunkpos447= G->thunkpos; if (!yy_Sp(G)) { goto l447; } if (!yy_Ticks2(G)) { goto l447; } goto l434; - l447:; G->pos= yypos447; G->thunkpos= yythunkpos447; - } - { int yypos448= G->pos, yythunkpos448= G->thunkpos; if (!yy_Spacechar(G)) { goto l449; } goto l448; - l449:; G->pos= yypos448; G->thunkpos= yythunkpos448; if (!yy_Newline(G)) { goto l434; } - { int yypos450= G->pos, yythunkpos450= G->thunkpos; if (!yy_BlankLine(G)) { goto l450; } goto l434; - l450:; G->pos= yypos450; G->thunkpos= yythunkpos450; - } - } - l448:; - } - l437:; - l435:; - { int yypos436= G->pos, yythunkpos436= G->thunkpos; - { int yypos451= G->pos, yythunkpos451= G->thunkpos; - { int yypos455= G->pos, yythunkpos455= G->thunkpos; if (!yymatchChar(G, '`')) goto l455; goto l452; - l455:; G->pos= yypos455; G->thunkpos= yythunkpos455; - } if (!yy_Nonspacechar(G)) { goto l452; } - l453:; - { int yypos454= G->pos, yythunkpos454= G->thunkpos; - { int yypos456= G->pos, yythunkpos456= G->thunkpos; if (!yymatchChar(G, '`')) goto l456; goto l454; - l456:; G->pos= yypos456; G->thunkpos= yythunkpos456; - } if (!yy_Nonspacechar(G)) { goto l454; } goto l453; - l454:; G->pos= yypos454; G->thunkpos= yythunkpos454; - } goto l451; - l452:; G->pos= yypos451; G->thunkpos= yythunkpos451; - { int yypos458= G->pos, yythunkpos458= G->thunkpos; if (!yy_Ticks2(G)) { goto l458; } goto l457; - l458:; G->pos= yypos458; G->thunkpos= yythunkpos458; - } if (!yymatchChar(G, '`')) goto l457; - l459:; - { int yypos460= G->pos, yythunkpos460= G->thunkpos; if (!yymatchChar(G, '`')) goto l460; goto l459; - l460:; G->pos= yypos460; G->thunkpos= yythunkpos460; - } goto l451; - l457:; G->pos= yypos451; G->thunkpos= yythunkpos451; - { int yypos461= G->pos, yythunkpos461= G->thunkpos; if (!yy_Sp(G)) { goto l461; } if (!yy_Ticks2(G)) { goto l461; } goto l436; - l461:; G->pos= yypos461; G->thunkpos= yythunkpos461; - } - { int yypos462= G->pos, yythunkpos462= G->thunkpos; if (!yy_Spacechar(G)) { goto l463; } goto l462; - l463:; G->pos= yypos462; G->thunkpos= yythunkpos462; if (!yy_Newline(G)) { goto l436; } - { int yypos464= G->pos, yythunkpos464= G->thunkpos; if (!yy_BlankLine(G)) { goto l464; } goto l436; - l464:; G->pos= yypos464; G->thunkpos= yythunkpos464; - } - } - l462:; - } - l451:; goto l435; - l436:; G->pos= yypos436; G->thunkpos= yythunkpos436; - } if (!yy_Sp(G)) { goto l434; } if (!yy_Ticks2(G)) { goto l434; } goto l402; - l434:; G->pos= yypos402; G->thunkpos= yythunkpos402; if (!yy_Ticks3(G)) { goto l465; } yyDo(G, yySet, -1, 0); if (!yy_Sp(G)) { goto l465; } - { int yypos468= G->pos, yythunkpos468= G->thunkpos; - { int yypos472= G->pos, yythunkpos472= G->thunkpos; if (!yymatchChar(G, '`')) goto l472; goto l469; - l472:; G->pos= yypos472; G->thunkpos= yythunkpos472; - } if (!yy_Nonspacechar(G)) { goto l469; } - l470:; - { int yypos471= G->pos, yythunkpos471= G->thunkpos; - { int yypos473= G->pos, yythunkpos473= G->thunkpos; if (!yymatchChar(G, '`')) goto l473; goto l471; - l473:; G->pos= yypos473; G->thunkpos= yythunkpos473; - } if (!yy_Nonspacechar(G)) { goto l471; } goto l470; - l471:; G->pos= yypos471; G->thunkpos= yythunkpos471; - } goto l468; - l469:; G->pos= yypos468; G->thunkpos= yythunkpos468; - { int yypos475= G->pos, yythunkpos475= G->thunkpos; if (!yy_Ticks3(G)) { goto l475; } goto l474; - l475:; G->pos= yypos475; G->thunkpos= yythunkpos475; - } if (!yymatchChar(G, '`')) goto l474; - l476:; - { int yypos477= G->pos, yythunkpos477= G->thunkpos; if (!yymatchChar(G, '`')) goto l477; goto l476; - l477:; G->pos= yypos477; G->thunkpos= yythunkpos477; - } goto l468; - l474:; G->pos= yypos468; G->thunkpos= yythunkpos468; - { int yypos478= G->pos, yythunkpos478= G->thunkpos; if (!yy_Sp(G)) { goto l478; } if (!yy_Ticks3(G)) { goto l478; } goto l465; - l478:; G->pos= yypos478; G->thunkpos= yythunkpos478; - } - { int yypos479= G->pos, yythunkpos479= G->thunkpos; if (!yy_Spacechar(G)) { goto l480; } goto l479; - l480:; G->pos= yypos479; G->thunkpos= yythunkpos479; if (!yy_Newline(G)) { goto l465; } - { int yypos481= G->pos, yythunkpos481= G->thunkpos; if (!yy_BlankLine(G)) { goto l481; } goto l465; - l481:; G->pos= yypos481; G->thunkpos= yythunkpos481; - } - } - l479:; - } - l468:; - l466:; - { int yypos467= G->pos, yythunkpos467= G->thunkpos; - { int yypos482= G->pos, yythunkpos482= G->thunkpos; - { int yypos486= G->pos, yythunkpos486= G->thunkpos; if (!yymatchChar(G, '`')) goto l486; goto l483; - l486:; G->pos= yypos486; G->thunkpos= yythunkpos486; - } if (!yy_Nonspacechar(G)) { goto l483; } - l484:; - { int yypos485= G->pos, yythunkpos485= G->thunkpos; - { int yypos487= G->pos, yythunkpos487= G->thunkpos; if (!yymatchChar(G, '`')) goto l487; goto l485; - l487:; G->pos= yypos487; G->thunkpos= yythunkpos487; - } if (!yy_Nonspacechar(G)) { goto l485; } goto l484; - l485:; G->pos= yypos485; G->thunkpos= yythunkpos485; - } goto l482; - l483:; G->pos= yypos482; G->thunkpos= yythunkpos482; - { int yypos489= G->pos, yythunkpos489= G->thunkpos; if (!yy_Ticks3(G)) { goto l489; } goto l488; - l489:; G->pos= yypos489; G->thunkpos= yythunkpos489; - } if (!yymatchChar(G, '`')) goto l488; - l490:; - { int yypos491= G->pos, yythunkpos491= G->thunkpos; if (!yymatchChar(G, '`')) goto l491; goto l490; - l491:; G->pos= yypos491; G->thunkpos= yythunkpos491; - } goto l482; - l488:; G->pos= yypos482; G->thunkpos= yythunkpos482; - { int yypos492= G->pos, yythunkpos492= G->thunkpos; if (!yy_Sp(G)) { goto l492; } if (!yy_Ticks3(G)) { goto l492; } goto l467; - l492:; G->pos= yypos492; G->thunkpos= yythunkpos492; - } - { int yypos493= G->pos, yythunkpos493= G->thunkpos; if (!yy_Spacechar(G)) { goto l494; } goto l493; - l494:; G->pos= yypos493; G->thunkpos= yythunkpos493; if (!yy_Newline(G)) { goto l467; } - { int yypos495= G->pos, yythunkpos495= G->thunkpos; if (!yy_BlankLine(G)) { goto l495; } goto l467; - l495:; G->pos= yypos495; G->thunkpos= yythunkpos495; - } - } - l493:; - } - l482:; goto l466; - l467:; G->pos= yypos467; G->thunkpos= yythunkpos467; - } if (!yy_Sp(G)) { goto l465; } if (!yy_Ticks3(G)) { goto l465; } goto l402; - l465:; G->pos= yypos402; G->thunkpos= yythunkpos402; if (!yy_Ticks4(G)) { goto l496; } yyDo(G, yySet, -1, 0); if (!yy_Sp(G)) { goto l496; } - { int yypos499= G->pos, yythunkpos499= G->thunkpos; - { int yypos503= G->pos, yythunkpos503= G->thunkpos; if (!yymatchChar(G, '`')) goto l503; goto l500; - l503:; G->pos= yypos503; G->thunkpos= yythunkpos503; - } if (!yy_Nonspacechar(G)) { goto l500; } - l501:; - { int yypos502= G->pos, yythunkpos502= G->thunkpos; - { int yypos504= G->pos, yythunkpos504= G->thunkpos; if (!yymatchChar(G, '`')) goto l504; goto l502; - l504:; G->pos= yypos504; G->thunkpos= yythunkpos504; - } if (!yy_Nonspacechar(G)) { goto l502; } goto l501; - l502:; G->pos= yypos502; G->thunkpos= yythunkpos502; - } goto l499; - l500:; G->pos= yypos499; G->thunkpos= yythunkpos499; - { int yypos506= G->pos, yythunkpos506= G->thunkpos; if (!yy_Ticks4(G)) { goto l506; } goto l505; - l506:; G->pos= yypos506; G->thunkpos= yythunkpos506; - } if (!yymatchChar(G, '`')) goto l505; - l507:; - { int yypos508= G->pos, yythunkpos508= G->thunkpos; if (!yymatchChar(G, '`')) goto l508; goto l507; - l508:; G->pos= yypos508; G->thunkpos= yythunkpos508; - } goto l499; - l505:; G->pos= yypos499; G->thunkpos= yythunkpos499; - { int yypos509= G->pos, yythunkpos509= G->thunkpos; if (!yy_Sp(G)) { goto l509; } if (!yy_Ticks4(G)) { goto l509; } goto l496; - l509:; G->pos= yypos509; G->thunkpos= yythunkpos509; - } - { int yypos510= G->pos, yythunkpos510= G->thunkpos; if (!yy_Spacechar(G)) { goto l511; } goto l510; - l511:; G->pos= yypos510; G->thunkpos= yythunkpos510; if (!yy_Newline(G)) { goto l496; } - { int yypos512= G->pos, yythunkpos512= G->thunkpos; if (!yy_BlankLine(G)) { goto l512; } goto l496; - l512:; G->pos= yypos512; G->thunkpos= yythunkpos512; - } - } - l510:; - } - l499:; - l497:; - { int yypos498= G->pos, yythunkpos498= G->thunkpos; - { int yypos513= G->pos, yythunkpos513= G->thunkpos; - { int yypos517= G->pos, yythunkpos517= G->thunkpos; if (!yymatchChar(G, '`')) goto l517; goto l514; - l517:; G->pos= yypos517; G->thunkpos= yythunkpos517; - } if (!yy_Nonspacechar(G)) { goto l514; } - l515:; - { int yypos516= G->pos, yythunkpos516= G->thunkpos; - { int yypos518= G->pos, yythunkpos518= G->thunkpos; if (!yymatchChar(G, '`')) goto l518; goto l516; - l518:; G->pos= yypos518; G->thunkpos= yythunkpos518; - } if (!yy_Nonspacechar(G)) { goto l516; } goto l515; - l516:; G->pos= yypos516; G->thunkpos= yythunkpos516; - } goto l513; - l514:; G->pos= yypos513; G->thunkpos= yythunkpos513; - { int yypos520= G->pos, yythunkpos520= G->thunkpos; if (!yy_Ticks4(G)) { goto l520; } goto l519; - l520:; G->pos= yypos520; G->thunkpos= yythunkpos520; - } if (!yymatchChar(G, '`')) goto l519; - l521:; - { int yypos522= G->pos, yythunkpos522= G->thunkpos; if (!yymatchChar(G, '`')) goto l522; goto l521; - l522:; G->pos= yypos522; G->thunkpos= yythunkpos522; - } goto l513; - l519:; G->pos= yypos513; G->thunkpos= yythunkpos513; - { int yypos523= G->pos, yythunkpos523= G->thunkpos; if (!yy_Sp(G)) { goto l523; } if (!yy_Ticks4(G)) { goto l523; } goto l498; - l523:; G->pos= yypos523; G->thunkpos= yythunkpos523; - } - { int yypos524= G->pos, yythunkpos524= G->thunkpos; if (!yy_Spacechar(G)) { goto l525; } goto l524; - l525:; G->pos= yypos524; G->thunkpos= yythunkpos524; if (!yy_Newline(G)) { goto l498; } - { int yypos526= G->pos, yythunkpos526= G->thunkpos; if (!yy_BlankLine(G)) { goto l526; } goto l498; - l526:; G->pos= yypos526; G->thunkpos= yythunkpos526; - } - } - l524:; - } - l513:; goto l497; - l498:; G->pos= yypos498; G->thunkpos= yythunkpos498; - } if (!yy_Sp(G)) { goto l496; } if (!yy_Ticks4(G)) { goto l496; } goto l402; - l496:; G->pos= yypos402; G->thunkpos= yythunkpos402; if (!yy_Ticks5(G)) { goto l401; } yyDo(G, yySet, -1, 0); if (!yy_Sp(G)) { goto l401; } - { int yypos529= G->pos, yythunkpos529= G->thunkpos; - { int yypos533= G->pos, yythunkpos533= G->thunkpos; if (!yymatchChar(G, '`')) goto l533; goto l530; - l533:; G->pos= yypos533; G->thunkpos= yythunkpos533; - } if (!yy_Nonspacechar(G)) { goto l530; } - l531:; - { int yypos532= G->pos, yythunkpos532= G->thunkpos; - { int yypos534= G->pos, yythunkpos534= G->thunkpos; if (!yymatchChar(G, '`')) goto l534; goto l532; - l534:; G->pos= yypos534; G->thunkpos= yythunkpos534; - } if (!yy_Nonspacechar(G)) { goto l532; } goto l531; - l532:; G->pos= yypos532; G->thunkpos= yythunkpos532; - } goto l529; - l530:; G->pos= yypos529; G->thunkpos= yythunkpos529; - { int yypos536= G->pos, yythunkpos536= G->thunkpos; if (!yy_Ticks5(G)) { goto l536; } goto l535; - l536:; G->pos= yypos536; G->thunkpos= yythunkpos536; - } if (!yymatchChar(G, '`')) goto l535; - l537:; - { int yypos538= G->pos, yythunkpos538= G->thunkpos; if (!yymatchChar(G, '`')) goto l538; goto l537; - l538:; G->pos= yypos538; G->thunkpos= yythunkpos538; - } goto l529; - l535:; G->pos= yypos529; G->thunkpos= yythunkpos529; - { int yypos539= G->pos, yythunkpos539= G->thunkpos; if (!yy_Sp(G)) { goto l539; } if (!yy_Ticks5(G)) { goto l539; } goto l401; - l539:; G->pos= yypos539; G->thunkpos= yythunkpos539; - } - { int yypos540= G->pos, yythunkpos540= G->thunkpos; if (!yy_Spacechar(G)) { goto l541; } goto l540; - l541:; G->pos= yypos540; G->thunkpos= yythunkpos540; if (!yy_Newline(G)) { goto l401; } - { int yypos542= G->pos, yythunkpos542= G->thunkpos; if (!yy_BlankLine(G)) { goto l542; } goto l401; - l542:; G->pos= yypos542; G->thunkpos= yythunkpos542; - } - } - l540:; - } - l529:; - l527:; - { int yypos528= G->pos, yythunkpos528= G->thunkpos; - { int yypos543= G->pos, yythunkpos543= G->thunkpos; - { int yypos547= G->pos, yythunkpos547= G->thunkpos; if (!yymatchChar(G, '`')) goto l547; goto l544; - l547:; G->pos= yypos547; G->thunkpos= yythunkpos547; - } if (!yy_Nonspacechar(G)) { goto l544; } - l545:; - { int yypos546= G->pos, yythunkpos546= G->thunkpos; - { int yypos548= G->pos, yythunkpos548= G->thunkpos; if (!yymatchChar(G, '`')) goto l548; goto l546; - l548:; G->pos= yypos548; G->thunkpos= yythunkpos548; - } if (!yy_Nonspacechar(G)) { goto l546; } goto l545; - l546:; G->pos= yypos546; G->thunkpos= yythunkpos546; - } goto l543; - l544:; G->pos= yypos543; G->thunkpos= yythunkpos543; - { int yypos550= G->pos, yythunkpos550= G->thunkpos; if (!yy_Ticks5(G)) { goto l550; } goto l549; - l550:; G->pos= yypos550; G->thunkpos= yythunkpos550; - } if (!yymatchChar(G, '`')) goto l549; - l551:; - { int yypos552= G->pos, yythunkpos552= G->thunkpos; if (!yymatchChar(G, '`')) goto l552; goto l551; - l552:; G->pos= yypos552; G->thunkpos= yythunkpos552; - } goto l543; - l549:; G->pos= yypos543; G->thunkpos= yythunkpos543; - { int yypos553= G->pos, yythunkpos553= G->thunkpos; if (!yy_Sp(G)) { goto l553; } if (!yy_Ticks5(G)) { goto l553; } goto l528; - l553:; G->pos= yypos553; G->thunkpos= yythunkpos553; - } - { int yypos554= G->pos, yythunkpos554= G->thunkpos; if (!yy_Spacechar(G)) { goto l555; } goto l554; - l555:; G->pos= yypos554; G->thunkpos= yythunkpos554; if (!yy_Newline(G)) { goto l528; } - { int yypos556= G->pos, yythunkpos556= G->thunkpos; if (!yy_BlankLine(G)) { goto l556; } goto l528; - l556:; G->pos= yypos556; G->thunkpos= yythunkpos556; - } - } - l554:; - } - l543:; goto l527; - l528:; G->pos= yypos528; G->thunkpos= yythunkpos528; - } if (!yy_Sp(G)) { goto l401; } if (!yy_Ticks5(G)) { goto l401; } - } - l402:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l401; yyDo(G, yy_1_Code, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Code", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l401:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Code", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_InlineNote(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "InlineNote")); yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_NOTES) )) goto l557; if (!yymatchString(G, "^[")) goto l557; - { int yypos560= G->pos, yythunkpos560= G->thunkpos; if (!yymatchChar(G, ']')) goto l560; goto l557; - l560:; G->pos= yypos560; G->thunkpos= yythunkpos560; - } if (!yy_Inline(G)) { goto l557; } - l558:; - { int yypos559= G->pos, yythunkpos559= G->thunkpos; - { int yypos561= G->pos, yythunkpos561= G->thunkpos; if (!yymatchChar(G, ']')) goto l561; goto l559; - l561:; G->pos= yypos561; G->thunkpos= yythunkpos561; - } if (!yy_Inline(G)) { goto l559; } goto l558; - l559:; G->pos= yypos559; G->thunkpos= yythunkpos559; - } if (!yymatchChar(G, ']')) goto l557; - yyprintf((stderr, " ok %s @ %s\n", "InlineNote", G->buf+G->pos)); - return 1; - l557:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "InlineNote", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_NoteReference(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "NoteReference")); yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_NOTES) )) goto l562; if (!yy_RawNoteReference(G)) { goto l562; } - yyprintf((stderr, " ok %s @ %s\n", "NoteReference", G->buf+G->pos)); - return 1; - l562:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "NoteReference", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Link(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Link")); - { int yypos564= G->pos, yythunkpos564= G->thunkpos; if (!yy_ExplicitLink(G)) { goto l565; } goto l564; - l565:; G->pos= yypos564; G->thunkpos= yythunkpos564; if (!yy_ReferenceLink(G)) { goto l566; } goto l564; - l566:; G->pos= yypos564; G->thunkpos= yythunkpos564; if (!yy_AutoLink(G)) { goto l563; } - } - l564:; yyDo(G, yy_1_Link, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Link", G->buf+G->pos)); - return 1; - l563:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Link", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Image(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Image")); if (!yymatchChar(G, '!')) goto l567; - { int yypos568= G->pos, yythunkpos568= G->thunkpos; if (!yy_ExplicitLink(G)) { goto l569; } goto l568; - l569:; G->pos= yypos568; G->thunkpos= yythunkpos568; if (!yy_ReferenceLink(G)) { goto l567; } - } - l568:; yyDo(G, yy_1_Image, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Image", G->buf+G->pos)); - return 1; - l567:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Image", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Strike(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "Strike")); yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_STRIKE) )) goto l570; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l570; if (!yy_LocMarker(G)) { goto l570; } yyDo(G, yySet, -1, 0); if (!yymatchString(G, "~~")) goto l570; - { int yypos571= G->pos, yythunkpos571= G->thunkpos; if (!yy_Whitespace(G)) { goto l571; } goto l570; - l571:; G->pos= yypos571; G->thunkpos= yythunkpos571; - } - { int yypos574= G->pos, yythunkpos574= G->thunkpos; if (!yymatchString(G, "~~")) goto l574; goto l570; - l574:; G->pos= yypos574; G->thunkpos= yythunkpos574; - } if (!yy_Inline(G)) { goto l570; } - l572:; - { int yypos573= G->pos, yythunkpos573= G->thunkpos; - { int yypos575= G->pos, yythunkpos575= G->thunkpos; if (!yymatchString(G, "~~")) goto l575; goto l573; - l575:; G->pos= yypos575; G->thunkpos= yythunkpos575; - } if (!yy_Inline(G)) { goto l573; } goto l572; - l573:; G->pos= yypos573; G->thunkpos= yythunkpos573; - } if (!yymatchString(G, "~~")) goto l570; yyText(G, G->begin, G->end); if (!(YY_END)) goto l570; yyDo(G, yy_1_Strike, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Strike", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l570:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Strike", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Emph(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Emph")); - { int yypos577= G->pos, yythunkpos577= G->thunkpos; if (!yy_EmphStar(G)) { goto l578; } goto l577; - l578:; G->pos= yypos577; G->thunkpos= yythunkpos577; if (!yy_EmphUl(G)) { goto l576; } - } - l577:; - yyprintf((stderr, " ok %s @ %s\n", "Emph", G->buf+G->pos)); - return 1; - l576:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Emph", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Strong(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Strong")); - { int yypos580= G->pos, yythunkpos580= G->thunkpos; if (!yy_StrongStar(G)) { goto l581; } goto l580; - l581:; G->pos= yypos580; G->thunkpos= yythunkpos580; if (!yy_StrongUl(G)) { goto l579; } - } - l580:; - yyprintf((stderr, " ok %s @ %s\n", "Strong", G->buf+G->pos)); - return 1; - l579:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Strong", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Space(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Space")); if (!yy_Spacechar(G)) { goto l582; } - l583:; - { int yypos584= G->pos, yythunkpos584= G->thunkpos; if (!yy_Spacechar(G)) { goto l584; } goto l583; - l584:; G->pos= yypos584; G->thunkpos= yythunkpos584; - } - yyprintf((stderr, " ok %s @ %s\n", "Space", G->buf+G->pos)); - return 1; - l582:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Space", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_UlOrStarLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "UlOrStarLine")); - { int yypos586= G->pos, yythunkpos586= G->thunkpos; if (!yy_UlLine(G)) { goto l587; } goto l586; - l587:; G->pos= yypos586; G->thunkpos= yythunkpos586; if (!yy_StarLine(G)) { goto l585; } - } - l586:; - yyprintf((stderr, " ok %s @ %s\n", "UlOrStarLine", G->buf+G->pos)); - return 1; - l585:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "UlOrStarLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Str(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Str")); if (!yy_NormalChar(G)) { goto l588; } - l589:; - { int yypos590= G->pos, yythunkpos590= G->thunkpos; - { int yypos591= G->pos, yythunkpos591= G->thunkpos; if (!yy_NormalChar(G)) { goto l592; } goto l591; - l592:; G->pos= yypos591; G->thunkpos= yythunkpos591; if (!yymatchChar(G, '_')) goto l590; - l593:; - { int yypos594= G->pos, yythunkpos594= G->thunkpos; if (!yymatchChar(G, '_')) goto l594; goto l593; - l594:; G->pos= yypos594; G->thunkpos= yythunkpos594; - } - { int yypos595= G->pos, yythunkpos595= G->thunkpos; if (!yy_Alphanumeric(G)) { goto l590; } G->pos= yypos595; G->thunkpos= yythunkpos595; - } - } - l591:; goto l589; - l590:; G->pos= yypos590; G->thunkpos= yythunkpos590; - } - yyprintf((stderr, " ok %s @ %s\n", "Str", G->buf+G->pos)); - return 1; - l588:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Str", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_InStyleTags(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "InStyleTags")); if (!yy_StyleOpen(G)) { goto l596; } - l597:; - { int yypos598= G->pos, yythunkpos598= G->thunkpos; - { int yypos599= G->pos, yythunkpos599= G->thunkpos; if (!yy_StyleClose(G)) { goto l599; } goto l598; - l599:; G->pos= yypos599; G->thunkpos= yythunkpos599; - } if (!yymatchDot(G)) goto l598; goto l597; - l598:; G->pos= yypos598; G->thunkpos= yythunkpos598; - } if (!yy_StyleClose(G)) { goto l596; } - yyprintf((stderr, " ok %s @ %s\n", "InStyleTags", G->buf+G->pos)); - return 1; - l596:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "InStyleTags", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_StyleClose(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "StyleClose")); if (!yymatchChar(G, '<')) goto l600; if (!yy_Spnl(G)) { goto l600; } if (!yymatchChar(G, '/')) goto l600; - { int yypos601= G->pos, yythunkpos601= G->thunkpos; if (!yymatchString(G, "style")) goto l602; goto l601; - l602:; G->pos= yypos601; G->thunkpos= yythunkpos601; if (!yymatchString(G, "STYLE")) goto l600; - } - l601:; if (!yy_Spnl(G)) { goto l600; } if (!yymatchChar(G, '>')) goto l600; - yyprintf((stderr, " ok %s @ %s\n", "StyleClose", G->buf+G->pos)); - return 1; - l600:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "StyleClose", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_StyleOpen(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "StyleOpen")); if (!yymatchChar(G, '<')) goto l603; if (!yy_Spnl(G)) { goto l603; } - { int yypos604= G->pos, yythunkpos604= G->thunkpos; if (!yymatchString(G, "style")) goto l605; goto l604; - l605:; G->pos= yypos604; G->thunkpos= yythunkpos604; if (!yymatchString(G, "STYLE")) goto l603; - } - l604:; if (!yy_Spnl(G)) { goto l603; } - l606:; - { int yypos607= G->pos, yythunkpos607= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l607; } goto l606; - l607:; G->pos= yypos607; G->thunkpos= yythunkpos607; - } if (!yymatchChar(G, '>')) goto l603; - yyprintf((stderr, " ok %s @ %s\n", "StyleOpen", G->buf+G->pos)); - return 1; - l603:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "StyleOpen", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockType(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockType")); - { int yypos609= G->pos, yythunkpos609= G->thunkpos; if (!yymatchString(G, "address")) goto l610; goto l609; - l610:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "blockquote")) goto l611; goto l609; - l611:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "center")) goto l612; goto l609; - l612:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "dir")) goto l613; goto l609; - l613:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "div")) goto l614; goto l609; - l614:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "dl")) goto l615; goto l609; - l615:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "fieldset")) goto l616; goto l609; - l616:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "form")) goto l617; goto l609; - l617:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "h1")) goto l618; goto l609; - l618:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "h2")) goto l619; goto l609; - l619:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "h3")) goto l620; goto l609; - l620:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "h4")) goto l621; goto l609; - l621:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "h5")) goto l622; goto l609; - l622:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "h6")) goto l623; goto l609; - l623:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "hr")) goto l624; goto l609; - l624:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "isindex")) goto l625; goto l609; - l625:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "menu")) goto l626; goto l609; - l626:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "noframes")) goto l627; goto l609; - l627:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "noscript")) goto l628; goto l609; - l628:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "ol")) goto l629; goto l609; - l629:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchChar(G, 'p')) goto l630; goto l609; - l630:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "pre")) goto l631; goto l609; - l631:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "table")) goto l632; goto l609; - l632:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "ul")) goto l633; goto l609; - l633:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "dd")) goto l634; goto l609; - l634:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "dt")) goto l635; goto l609; - l635:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "frameset")) goto l636; goto l609; - l636:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "li")) goto l637; goto l609; - l637:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "tbody")) goto l638; goto l609; - l638:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "td")) goto l639; goto l609; - l639:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "tfoot")) goto l640; goto l609; - l640:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "th")) goto l641; goto l609; - l641:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "thead")) goto l642; goto l609; - l642:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "tr")) goto l643; goto l609; - l643:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "script")) goto l644; goto l609; - l644:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "ADDRESS")) goto l645; goto l609; - l645:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "BLOCKQUOTE")) goto l646; goto l609; - l646:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "CENTER")) goto l647; goto l609; - l647:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "DIR")) goto l648; goto l609; - l648:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "DIV")) goto l649; goto l609; - l649:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "DL")) goto l650; goto l609; - l650:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "FIELDSET")) goto l651; goto l609; - l651:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "FORM")) goto l652; goto l609; - l652:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "H1")) goto l653; goto l609; - l653:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "H2")) goto l654; goto l609; - l654:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "H3")) goto l655; goto l609; - l655:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "H4")) goto l656; goto l609; - l656:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "H5")) goto l657; goto l609; - l657:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "H6")) goto l658; goto l609; - l658:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "HR")) goto l659; goto l609; - l659:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "ISINDEX")) goto l660; goto l609; - l660:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "MENU")) goto l661; goto l609; - l661:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "NOFRAMES")) goto l662; goto l609; - l662:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "NOSCRIPT")) goto l663; goto l609; - l663:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "OL")) goto l664; goto l609; - l664:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchChar(G, 'P')) goto l665; goto l609; - l665:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "PRE")) goto l666; goto l609; - l666:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "TABLE")) goto l667; goto l609; - l667:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "UL")) goto l668; goto l609; - l668:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "DD")) goto l669; goto l609; - l669:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "DT")) goto l670; goto l609; - l670:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "FRAMESET")) goto l671; goto l609; - l671:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "LI")) goto l672; goto l609; - l672:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "TBODY")) goto l673; goto l609; - l673:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "TD")) goto l674; goto l609; - l674:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "TFOOT")) goto l675; goto l609; - l675:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "TH")) goto l676; goto l609; - l676:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "THEAD")) goto l677; goto l609; - l677:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "TR")) goto l678; goto l609; - l678:; G->pos= yypos609; G->thunkpos= yythunkpos609; if (!yymatchString(G, "SCRIPT")) goto l608; - } - l609:; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockType", G->buf+G->pos)); - return 1; - l608:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockType", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockSelfClosing(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockSelfClosing")); if (!yymatchChar(G, '<')) goto l679; if (!yy_Spnl(G)) { goto l679; } if (!yy_HtmlBlockType(G)) { goto l679; } if (!yy_Spnl(G)) { goto l679; } - l680:; - { int yypos681= G->pos, yythunkpos681= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l681; } goto l680; - l681:; G->pos= yypos681; G->thunkpos= yythunkpos681; - } if (!yymatchChar(G, '/')) goto l679; if (!yy_Spnl(G)) { goto l679; } if (!yymatchChar(G, '>')) goto l679; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockSelfClosing", G->buf+G->pos)); - return 1; - l679:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockSelfClosing", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlComment(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "HtmlComment")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l682; if (!yy_LocMarker(G)) { goto l682; } yyDo(G, yySet, -1, 0); if (!yymatchString(G, "")) goto l685; goto l684; - l685:; G->pos= yypos685; G->thunkpos= yythunkpos685; - } if (!yymatchDot(G)) goto l684; goto l683; - l684:; G->pos= yypos684; G->thunkpos= yythunkpos684; - } if (!yymatchString(G, "-->")) goto l682; yyText(G, G->begin, G->end); if (!(YY_END)) goto l682; yyDo(G, yy_1_HtmlComment, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HtmlComment", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l682:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlComment", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockInTags(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockInTags")); - { int yypos687= G->pos, yythunkpos687= G->thunkpos; if (!yy_HtmlBlockAddress(G)) { goto l688; } goto l687; - l688:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockBlockquote(G)) { goto l689; } goto l687; - l689:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockCenter(G)) { goto l690; } goto l687; - l690:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockDir(G)) { goto l691; } goto l687; - l691:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockDiv(G)) { goto l692; } goto l687; - l692:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockDl(G)) { goto l693; } goto l687; - l693:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockFieldset(G)) { goto l694; } goto l687; - l694:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockForm(G)) { goto l695; } goto l687; - l695:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockH1(G)) { goto l696; } goto l687; - l696:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockH2(G)) { goto l697; } goto l687; - l697:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockH3(G)) { goto l698; } goto l687; - l698:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockH4(G)) { goto l699; } goto l687; - l699:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockH5(G)) { goto l700; } goto l687; - l700:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockH6(G)) { goto l701; } goto l687; - l701:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockMenu(G)) { goto l702; } goto l687; - l702:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockNoframes(G)) { goto l703; } goto l687; - l703:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockNoscript(G)) { goto l704; } goto l687; - l704:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockOl(G)) { goto l705; } goto l687; - l705:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockP(G)) { goto l706; } goto l687; - l706:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockPre(G)) { goto l707; } goto l687; - l707:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockTable(G)) { goto l708; } goto l687; - l708:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockUl(G)) { goto l709; } goto l687; - l709:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockDd(G)) { goto l710; } goto l687; - l710:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockDt(G)) { goto l711; } goto l687; - l711:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockFrameset(G)) { goto l712; } goto l687; - l712:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockLi(G)) { goto l713; } goto l687; - l713:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockTbody(G)) { goto l714; } goto l687; - l714:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockTd(G)) { goto l715; } goto l687; - l715:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockTfoot(G)) { goto l716; } goto l687; - l716:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockTh(G)) { goto l717; } goto l687; - l717:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockThead(G)) { goto l718; } goto l687; - l718:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockTr(G)) { goto l719; } goto l687; - l719:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockScript(G)) { goto l720; } goto l687; - l720:; G->pos= yypos687; G->thunkpos= yythunkpos687; if (!yy_HtmlBlockHead(G)) { goto l686; } - } - l687:; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockInTags", G->buf+G->pos)); - return 1; - l686:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockInTags", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockHead(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockHead")); if (!yy_HtmlBlockOpenHead(G)) { goto l721; } - l722:; - { int yypos723= G->pos, yythunkpos723= G->thunkpos; - { int yypos724= G->pos, yythunkpos724= G->thunkpos; if (!yy_HtmlBlockCloseHead(G)) { goto l724; } goto l723; - l724:; G->pos= yypos724; G->thunkpos= yythunkpos724; - } if (!yymatchDot(G)) goto l723; goto l722; - l723:; G->pos= yypos723; G->thunkpos= yythunkpos723; - } if (!yy_HtmlBlockCloseHead(G)) { goto l721; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockHead", G->buf+G->pos)); - return 1; - l721:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockHead", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseHead(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseHead")); if (!yymatchChar(G, '<')) goto l725; if (!yy_Spnl(G)) { goto l725; } if (!yymatchChar(G, '/')) goto l725; - { int yypos726= G->pos, yythunkpos726= G->thunkpos; if (!yymatchString(G, "head")) goto l727; goto l726; - l727:; G->pos= yypos726; G->thunkpos= yythunkpos726; if (!yymatchString(G, "HEAD")) goto l725; - } - l726:; if (!yy_Spnl(G)) { goto l725; } if (!yymatchChar(G, '>')) goto l725; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseHead", G->buf+G->pos)); - return 1; - l725:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseHead", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenHead(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenHead")); if (!yymatchChar(G, '<')) goto l728; if (!yy_Spnl(G)) { goto l728; } - { int yypos729= G->pos, yythunkpos729= G->thunkpos; if (!yymatchString(G, "head")) goto l730; goto l729; - l730:; G->pos= yypos729; G->thunkpos= yythunkpos729; if (!yymatchString(G, "HEAD")) goto l728; - } - l729:; if (!yy_Spnl(G)) { goto l728; } - l731:; - { int yypos732= G->pos, yythunkpos732= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l732; } goto l731; - l732:; G->pos= yypos732; G->thunkpos= yythunkpos732; - } if (!yymatchChar(G, '>')) goto l728; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenHead", G->buf+G->pos)); - return 1; - l728:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenHead", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockScript(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockScript")); if (!yy_HtmlBlockOpenScript(G)) { goto l733; } - l734:; - { int yypos735= G->pos, yythunkpos735= G->thunkpos; - { int yypos736= G->pos, yythunkpos736= G->thunkpos; if (!yy_HtmlBlockCloseScript(G)) { goto l736; } goto l735; - l736:; G->pos= yypos736; G->thunkpos= yythunkpos736; - } if (!yymatchDot(G)) goto l735; goto l734; - l735:; G->pos= yypos735; G->thunkpos= yythunkpos735; - } if (!yy_HtmlBlockCloseScript(G)) { goto l733; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockScript", G->buf+G->pos)); - return 1; - l733:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockScript", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseScript(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseScript")); if (!yymatchChar(G, '<')) goto l737; if (!yy_Spnl(G)) { goto l737; } if (!yymatchChar(G, '/')) goto l737; - { int yypos738= G->pos, yythunkpos738= G->thunkpos; if (!yymatchString(G, "script")) goto l739; goto l738; - l739:; G->pos= yypos738; G->thunkpos= yythunkpos738; if (!yymatchString(G, "SCRIPT")) goto l737; - } - l738:; if (!yy_Spnl(G)) { goto l737; } if (!yymatchChar(G, '>')) goto l737; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseScript", G->buf+G->pos)); - return 1; - l737:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseScript", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenScript(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenScript")); if (!yymatchChar(G, '<')) goto l740; if (!yy_Spnl(G)) { goto l740; } - { int yypos741= G->pos, yythunkpos741= G->thunkpos; if (!yymatchString(G, "script")) goto l742; goto l741; - l742:; G->pos= yypos741; G->thunkpos= yythunkpos741; if (!yymatchString(G, "SCRIPT")) goto l740; - } - l741:; if (!yy_Spnl(G)) { goto l740; } - l743:; - { int yypos744= G->pos, yythunkpos744= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l744; } goto l743; - l744:; G->pos= yypos744; G->thunkpos= yythunkpos744; - } if (!yymatchChar(G, '>')) goto l740; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenScript", G->buf+G->pos)); - return 1; - l740:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenScript", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockTr(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockTr")); if (!yy_HtmlBlockOpenTr(G)) { goto l745; } - l746:; - { int yypos747= G->pos, yythunkpos747= G->thunkpos; - { int yypos748= G->pos, yythunkpos748= G->thunkpos; if (!yy_HtmlBlockTr(G)) { goto l749; } goto l748; - l749:; G->pos= yypos748; G->thunkpos= yythunkpos748; - { int yypos750= G->pos, yythunkpos750= G->thunkpos; if (!yy_HtmlBlockCloseTr(G)) { goto l750; } goto l747; - l750:; G->pos= yypos750; G->thunkpos= yythunkpos750; - } if (!yymatchDot(G)) goto l747; - } - l748:; goto l746; - l747:; G->pos= yypos747; G->thunkpos= yythunkpos747; - } if (!yy_HtmlBlockCloseTr(G)) { goto l745; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTr", G->buf+G->pos)); - return 1; - l745:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTr", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseTr(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseTr")); if (!yymatchChar(G, '<')) goto l751; if (!yy_Spnl(G)) { goto l751; } if (!yymatchChar(G, '/')) goto l751; - { int yypos752= G->pos, yythunkpos752= G->thunkpos; if (!yymatchString(G, "tr")) goto l753; goto l752; - l753:; G->pos= yypos752; G->thunkpos= yythunkpos752; if (!yymatchString(G, "TR")) goto l751; - } - l752:; if (!yy_Spnl(G)) { goto l751; } if (!yymatchChar(G, '>')) goto l751; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTr", G->buf+G->pos)); - return 1; - l751:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTr", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenTr(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenTr")); if (!yymatchChar(G, '<')) goto l754; if (!yy_Spnl(G)) { goto l754; } - { int yypos755= G->pos, yythunkpos755= G->thunkpos; if (!yymatchString(G, "tr")) goto l756; goto l755; - l756:; G->pos= yypos755; G->thunkpos= yythunkpos755; if (!yymatchString(G, "TR")) goto l754; - } - l755:; if (!yy_Spnl(G)) { goto l754; } - l757:; - { int yypos758= G->pos, yythunkpos758= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l758; } goto l757; - l758:; G->pos= yypos758; G->thunkpos= yythunkpos758; - } if (!yymatchChar(G, '>')) goto l754; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTr", G->buf+G->pos)); - return 1; - l754:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTr", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockThead(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockThead")); if (!yy_HtmlBlockOpenThead(G)) { goto l759; } - l760:; - { int yypos761= G->pos, yythunkpos761= G->thunkpos; - { int yypos762= G->pos, yythunkpos762= G->thunkpos; if (!yy_HtmlBlockThead(G)) { goto l763; } goto l762; - l763:; G->pos= yypos762; G->thunkpos= yythunkpos762; - { int yypos764= G->pos, yythunkpos764= G->thunkpos; if (!yy_HtmlBlockCloseThead(G)) { goto l764; } goto l761; - l764:; G->pos= yypos764; G->thunkpos= yythunkpos764; - } if (!yymatchDot(G)) goto l761; - } - l762:; goto l760; - l761:; G->pos= yypos761; G->thunkpos= yythunkpos761; - } if (!yy_HtmlBlockCloseThead(G)) { goto l759; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockThead", G->buf+G->pos)); - return 1; - l759:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockThead", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseThead(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseThead")); if (!yymatchChar(G, '<')) goto l765; if (!yy_Spnl(G)) { goto l765; } if (!yymatchChar(G, '/')) goto l765; - { int yypos766= G->pos, yythunkpos766= G->thunkpos; if (!yymatchString(G, "thead")) goto l767; goto l766; - l767:; G->pos= yypos766; G->thunkpos= yythunkpos766; if (!yymatchString(G, "THEAD")) goto l765; - } - l766:; if (!yy_Spnl(G)) { goto l765; } if (!yymatchChar(G, '>')) goto l765; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseThead", G->buf+G->pos)); - return 1; - l765:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseThead", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenThead(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenThead")); if (!yymatchChar(G, '<')) goto l768; if (!yy_Spnl(G)) { goto l768; } - { int yypos769= G->pos, yythunkpos769= G->thunkpos; if (!yymatchString(G, "thead")) goto l770; goto l769; - l770:; G->pos= yypos769; G->thunkpos= yythunkpos769; if (!yymatchString(G, "THEAD")) goto l768; - } - l769:; if (!yy_Spnl(G)) { goto l768; } - l771:; - { int yypos772= G->pos, yythunkpos772= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l772; } goto l771; - l772:; G->pos= yypos772; G->thunkpos= yythunkpos772; - } if (!yymatchChar(G, '>')) goto l768; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenThead", G->buf+G->pos)); - return 1; - l768:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenThead", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockTh(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockTh")); if (!yy_HtmlBlockOpenTh(G)) { goto l773; } - l774:; - { int yypos775= G->pos, yythunkpos775= G->thunkpos; - { int yypos776= G->pos, yythunkpos776= G->thunkpos; if (!yy_HtmlBlockTh(G)) { goto l777; } goto l776; - l777:; G->pos= yypos776; G->thunkpos= yythunkpos776; - { int yypos778= G->pos, yythunkpos778= G->thunkpos; if (!yy_HtmlBlockCloseTh(G)) { goto l778; } goto l775; - l778:; G->pos= yypos778; G->thunkpos= yythunkpos778; - } if (!yymatchDot(G)) goto l775; - } - l776:; goto l774; - l775:; G->pos= yypos775; G->thunkpos= yythunkpos775; - } if (!yy_HtmlBlockCloseTh(G)) { goto l773; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTh", G->buf+G->pos)); - return 1; - l773:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTh", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseTh(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseTh")); if (!yymatchChar(G, '<')) goto l779; if (!yy_Spnl(G)) { goto l779; } if (!yymatchChar(G, '/')) goto l779; - { int yypos780= G->pos, yythunkpos780= G->thunkpos; if (!yymatchString(G, "th")) goto l781; goto l780; - l781:; G->pos= yypos780; G->thunkpos= yythunkpos780; if (!yymatchString(G, "TH")) goto l779; - } - l780:; if (!yy_Spnl(G)) { goto l779; } if (!yymatchChar(G, '>')) goto l779; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTh", G->buf+G->pos)); - return 1; - l779:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTh", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenTh(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenTh")); if (!yymatchChar(G, '<')) goto l782; if (!yy_Spnl(G)) { goto l782; } - { int yypos783= G->pos, yythunkpos783= G->thunkpos; if (!yymatchString(G, "th")) goto l784; goto l783; - l784:; G->pos= yypos783; G->thunkpos= yythunkpos783; if (!yymatchString(G, "TH")) goto l782; - } - l783:; if (!yy_Spnl(G)) { goto l782; } - l785:; - { int yypos786= G->pos, yythunkpos786= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l786; } goto l785; - l786:; G->pos= yypos786; G->thunkpos= yythunkpos786; - } if (!yymatchChar(G, '>')) goto l782; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTh", G->buf+G->pos)); - return 1; - l782:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTh", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockTfoot(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockTfoot")); if (!yy_HtmlBlockOpenTfoot(G)) { goto l787; } - l788:; - { int yypos789= G->pos, yythunkpos789= G->thunkpos; - { int yypos790= G->pos, yythunkpos790= G->thunkpos; if (!yy_HtmlBlockTfoot(G)) { goto l791; } goto l790; - l791:; G->pos= yypos790; G->thunkpos= yythunkpos790; - { int yypos792= G->pos, yythunkpos792= G->thunkpos; if (!yy_HtmlBlockCloseTfoot(G)) { goto l792; } goto l789; - l792:; G->pos= yypos792; G->thunkpos= yythunkpos792; - } if (!yymatchDot(G)) goto l789; - } - l790:; goto l788; - l789:; G->pos= yypos789; G->thunkpos= yythunkpos789; - } if (!yy_HtmlBlockCloseTfoot(G)) { goto l787; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTfoot", G->buf+G->pos)); - return 1; - l787:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTfoot", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseTfoot(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseTfoot")); if (!yymatchChar(G, '<')) goto l793; if (!yy_Spnl(G)) { goto l793; } if (!yymatchChar(G, '/')) goto l793; - { int yypos794= G->pos, yythunkpos794= G->thunkpos; if (!yymatchString(G, "tfoot")) goto l795; goto l794; - l795:; G->pos= yypos794; G->thunkpos= yythunkpos794; if (!yymatchString(G, "TFOOT")) goto l793; - } - l794:; if (!yy_Spnl(G)) { goto l793; } if (!yymatchChar(G, '>')) goto l793; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTfoot", G->buf+G->pos)); - return 1; - l793:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTfoot", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenTfoot(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenTfoot")); if (!yymatchChar(G, '<')) goto l796; if (!yy_Spnl(G)) { goto l796; } - { int yypos797= G->pos, yythunkpos797= G->thunkpos; if (!yymatchString(G, "tfoot")) goto l798; goto l797; - l798:; G->pos= yypos797; G->thunkpos= yythunkpos797; if (!yymatchString(G, "TFOOT")) goto l796; - } - l797:; if (!yy_Spnl(G)) { goto l796; } - l799:; - { int yypos800= G->pos, yythunkpos800= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l800; } goto l799; - l800:; G->pos= yypos800; G->thunkpos= yythunkpos800; - } if (!yymatchChar(G, '>')) goto l796; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTfoot", G->buf+G->pos)); - return 1; - l796:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTfoot", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockTd(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockTd")); if (!yy_HtmlBlockOpenTd(G)) { goto l801; } - l802:; - { int yypos803= G->pos, yythunkpos803= G->thunkpos; - { int yypos804= G->pos, yythunkpos804= G->thunkpos; if (!yy_HtmlBlockTd(G)) { goto l805; } goto l804; - l805:; G->pos= yypos804; G->thunkpos= yythunkpos804; - { int yypos806= G->pos, yythunkpos806= G->thunkpos; if (!yy_HtmlBlockCloseTd(G)) { goto l806; } goto l803; - l806:; G->pos= yypos806; G->thunkpos= yythunkpos806; - } if (!yymatchDot(G)) goto l803; - } - l804:; goto l802; - l803:; G->pos= yypos803; G->thunkpos= yythunkpos803; - } if (!yy_HtmlBlockCloseTd(G)) { goto l801; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTd", G->buf+G->pos)); - return 1; - l801:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTd", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseTd(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseTd")); if (!yymatchChar(G, '<')) goto l807; if (!yy_Spnl(G)) { goto l807; } if (!yymatchChar(G, '/')) goto l807; - { int yypos808= G->pos, yythunkpos808= G->thunkpos; if (!yymatchString(G, "td")) goto l809; goto l808; - l809:; G->pos= yypos808; G->thunkpos= yythunkpos808; if (!yymatchString(G, "TD")) goto l807; - } - l808:; if (!yy_Spnl(G)) { goto l807; } if (!yymatchChar(G, '>')) goto l807; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTd", G->buf+G->pos)); - return 1; - l807:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTd", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenTd(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenTd")); if (!yymatchChar(G, '<')) goto l810; if (!yy_Spnl(G)) { goto l810; } - { int yypos811= G->pos, yythunkpos811= G->thunkpos; if (!yymatchString(G, "td")) goto l812; goto l811; - l812:; G->pos= yypos811; G->thunkpos= yythunkpos811; if (!yymatchString(G, "TD")) goto l810; - } - l811:; if (!yy_Spnl(G)) { goto l810; } - l813:; - { int yypos814= G->pos, yythunkpos814= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l814; } goto l813; - l814:; G->pos= yypos814; G->thunkpos= yythunkpos814; - } if (!yymatchChar(G, '>')) goto l810; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTd", G->buf+G->pos)); - return 1; - l810:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTd", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockTbody(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockTbody")); if (!yy_HtmlBlockOpenTbody(G)) { goto l815; } - l816:; - { int yypos817= G->pos, yythunkpos817= G->thunkpos; - { int yypos818= G->pos, yythunkpos818= G->thunkpos; if (!yy_HtmlBlockTbody(G)) { goto l819; } goto l818; - l819:; G->pos= yypos818; G->thunkpos= yythunkpos818; - { int yypos820= G->pos, yythunkpos820= G->thunkpos; if (!yy_HtmlBlockCloseTbody(G)) { goto l820; } goto l817; - l820:; G->pos= yypos820; G->thunkpos= yythunkpos820; - } if (!yymatchDot(G)) goto l817; - } - l818:; goto l816; - l817:; G->pos= yypos817; G->thunkpos= yythunkpos817; - } if (!yy_HtmlBlockCloseTbody(G)) { goto l815; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTbody", G->buf+G->pos)); - return 1; - l815:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTbody", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseTbody(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseTbody")); if (!yymatchChar(G, '<')) goto l821; if (!yy_Spnl(G)) { goto l821; } if (!yymatchChar(G, '/')) goto l821; - { int yypos822= G->pos, yythunkpos822= G->thunkpos; if (!yymatchString(G, "tbody")) goto l823; goto l822; - l823:; G->pos= yypos822; G->thunkpos= yythunkpos822; if (!yymatchString(G, "TBODY")) goto l821; - } - l822:; if (!yy_Spnl(G)) { goto l821; } if (!yymatchChar(G, '>')) goto l821; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTbody", G->buf+G->pos)); - return 1; - l821:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTbody", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenTbody(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenTbody")); if (!yymatchChar(G, '<')) goto l824; if (!yy_Spnl(G)) { goto l824; } - { int yypos825= G->pos, yythunkpos825= G->thunkpos; if (!yymatchString(G, "tbody")) goto l826; goto l825; - l826:; G->pos= yypos825; G->thunkpos= yythunkpos825; if (!yymatchString(G, "TBODY")) goto l824; - } - l825:; if (!yy_Spnl(G)) { goto l824; } - l827:; - { int yypos828= G->pos, yythunkpos828= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l828; } goto l827; - l828:; G->pos= yypos828; G->thunkpos= yythunkpos828; - } if (!yymatchChar(G, '>')) goto l824; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTbody", G->buf+G->pos)); - return 1; - l824:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTbody", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockLi(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockLi")); if (!yy_HtmlBlockOpenLi(G)) { goto l829; } - l830:; - { int yypos831= G->pos, yythunkpos831= G->thunkpos; - { int yypos832= G->pos, yythunkpos832= G->thunkpos; if (!yy_HtmlBlockLi(G)) { goto l833; } goto l832; - l833:; G->pos= yypos832; G->thunkpos= yythunkpos832; - { int yypos834= G->pos, yythunkpos834= G->thunkpos; if (!yy_HtmlBlockCloseLi(G)) { goto l834; } goto l831; - l834:; G->pos= yypos834; G->thunkpos= yythunkpos834; - } if (!yymatchDot(G)) goto l831; - } - l832:; goto l830; - l831:; G->pos= yypos831; G->thunkpos= yythunkpos831; - } if (!yy_HtmlBlockCloseLi(G)) { goto l829; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockLi", G->buf+G->pos)); - return 1; - l829:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockLi", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseLi(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseLi")); if (!yymatchChar(G, '<')) goto l835; if (!yy_Spnl(G)) { goto l835; } if (!yymatchChar(G, '/')) goto l835; - { int yypos836= G->pos, yythunkpos836= G->thunkpos; if (!yymatchString(G, "li")) goto l837; goto l836; - l837:; G->pos= yypos836; G->thunkpos= yythunkpos836; if (!yymatchString(G, "LI")) goto l835; - } - l836:; if (!yy_Spnl(G)) { goto l835; } if (!yymatchChar(G, '>')) goto l835; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseLi", G->buf+G->pos)); - return 1; - l835:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseLi", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenLi(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenLi")); if (!yymatchChar(G, '<')) goto l838; if (!yy_Spnl(G)) { goto l838; } - { int yypos839= G->pos, yythunkpos839= G->thunkpos; if (!yymatchString(G, "li")) goto l840; goto l839; - l840:; G->pos= yypos839; G->thunkpos= yythunkpos839; if (!yymatchString(G, "LI")) goto l838; - } - l839:; if (!yy_Spnl(G)) { goto l838; } - l841:; - { int yypos842= G->pos, yythunkpos842= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l842; } goto l841; - l842:; G->pos= yypos842; G->thunkpos= yythunkpos842; - } if (!yymatchChar(G, '>')) goto l838; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenLi", G->buf+G->pos)); - return 1; - l838:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenLi", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockFrameset(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockFrameset")); if (!yy_HtmlBlockOpenFrameset(G)) { goto l843; } - l844:; - { int yypos845= G->pos, yythunkpos845= G->thunkpos; - { int yypos846= G->pos, yythunkpos846= G->thunkpos; if (!yy_HtmlBlockFrameset(G)) { goto l847; } goto l846; - l847:; G->pos= yypos846; G->thunkpos= yythunkpos846; - { int yypos848= G->pos, yythunkpos848= G->thunkpos; if (!yy_HtmlBlockCloseFrameset(G)) { goto l848; } goto l845; - l848:; G->pos= yypos848; G->thunkpos= yythunkpos848; - } if (!yymatchDot(G)) goto l845; - } - l846:; goto l844; - l845:; G->pos= yypos845; G->thunkpos= yythunkpos845; - } if (!yy_HtmlBlockCloseFrameset(G)) { goto l843; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockFrameset", G->buf+G->pos)); - return 1; - l843:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockFrameset", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseFrameset(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseFrameset")); if (!yymatchChar(G, '<')) goto l849; if (!yy_Spnl(G)) { goto l849; } if (!yymatchChar(G, '/')) goto l849; - { int yypos850= G->pos, yythunkpos850= G->thunkpos; if (!yymatchString(G, "frameset")) goto l851; goto l850; - l851:; G->pos= yypos850; G->thunkpos= yythunkpos850; if (!yymatchString(G, "FRAMESET")) goto l849; - } - l850:; if (!yy_Spnl(G)) { goto l849; } if (!yymatchChar(G, '>')) goto l849; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseFrameset", G->buf+G->pos)); - return 1; - l849:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseFrameset", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenFrameset(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenFrameset")); if (!yymatchChar(G, '<')) goto l852; if (!yy_Spnl(G)) { goto l852; } - { int yypos853= G->pos, yythunkpos853= G->thunkpos; if (!yymatchString(G, "frameset")) goto l854; goto l853; - l854:; G->pos= yypos853; G->thunkpos= yythunkpos853; if (!yymatchString(G, "FRAMESET")) goto l852; - } - l853:; if (!yy_Spnl(G)) { goto l852; } - l855:; - { int yypos856= G->pos, yythunkpos856= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l856; } goto l855; - l856:; G->pos= yypos856; G->thunkpos= yythunkpos856; - } if (!yymatchChar(G, '>')) goto l852; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenFrameset", G->buf+G->pos)); - return 1; - l852:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenFrameset", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockDt(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockDt")); if (!yy_HtmlBlockOpenDt(G)) { goto l857; } - l858:; - { int yypos859= G->pos, yythunkpos859= G->thunkpos; - { int yypos860= G->pos, yythunkpos860= G->thunkpos; if (!yy_HtmlBlockDt(G)) { goto l861; } goto l860; - l861:; G->pos= yypos860; G->thunkpos= yythunkpos860; - { int yypos862= G->pos, yythunkpos862= G->thunkpos; if (!yy_HtmlBlockCloseDt(G)) { goto l862; } goto l859; - l862:; G->pos= yypos862; G->thunkpos= yythunkpos862; - } if (!yymatchDot(G)) goto l859; - } - l860:; goto l858; - l859:; G->pos= yypos859; G->thunkpos= yythunkpos859; - } if (!yy_HtmlBlockCloseDt(G)) { goto l857; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockDt", G->buf+G->pos)); - return 1; - l857:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockDt", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseDt(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseDt")); if (!yymatchChar(G, '<')) goto l863; if (!yy_Spnl(G)) { goto l863; } if (!yymatchChar(G, '/')) goto l863; - { int yypos864= G->pos, yythunkpos864= G->thunkpos; if (!yymatchString(G, "dt")) goto l865; goto l864; - l865:; G->pos= yypos864; G->thunkpos= yythunkpos864; if (!yymatchString(G, "DT")) goto l863; - } - l864:; if (!yy_Spnl(G)) { goto l863; } if (!yymatchChar(G, '>')) goto l863; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseDt", G->buf+G->pos)); - return 1; - l863:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseDt", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenDt(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenDt")); if (!yymatchChar(G, '<')) goto l866; if (!yy_Spnl(G)) { goto l866; } - { int yypos867= G->pos, yythunkpos867= G->thunkpos; if (!yymatchString(G, "dt")) goto l868; goto l867; - l868:; G->pos= yypos867; G->thunkpos= yythunkpos867; if (!yymatchString(G, "DT")) goto l866; - } - l867:; if (!yy_Spnl(G)) { goto l866; } - l869:; - { int yypos870= G->pos, yythunkpos870= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l870; } goto l869; - l870:; G->pos= yypos870; G->thunkpos= yythunkpos870; - } if (!yymatchChar(G, '>')) goto l866; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenDt", G->buf+G->pos)); - return 1; - l866:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenDt", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockDd(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockDd")); if (!yy_HtmlBlockOpenDd(G)) { goto l871; } - l872:; - { int yypos873= G->pos, yythunkpos873= G->thunkpos; - { int yypos874= G->pos, yythunkpos874= G->thunkpos; if (!yy_HtmlBlockDd(G)) { goto l875; } goto l874; - l875:; G->pos= yypos874; G->thunkpos= yythunkpos874; - { int yypos876= G->pos, yythunkpos876= G->thunkpos; if (!yy_HtmlBlockCloseDd(G)) { goto l876; } goto l873; - l876:; G->pos= yypos876; G->thunkpos= yythunkpos876; - } if (!yymatchDot(G)) goto l873; - } - l874:; goto l872; - l873:; G->pos= yypos873; G->thunkpos= yythunkpos873; - } if (!yy_HtmlBlockCloseDd(G)) { goto l871; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockDd", G->buf+G->pos)); - return 1; - l871:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockDd", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseDd(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseDd")); if (!yymatchChar(G, '<')) goto l877; if (!yy_Spnl(G)) { goto l877; } if (!yymatchChar(G, '/')) goto l877; - { int yypos878= G->pos, yythunkpos878= G->thunkpos; if (!yymatchString(G, "dd")) goto l879; goto l878; - l879:; G->pos= yypos878; G->thunkpos= yythunkpos878; if (!yymatchString(G, "DD")) goto l877; - } - l878:; if (!yy_Spnl(G)) { goto l877; } if (!yymatchChar(G, '>')) goto l877; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseDd", G->buf+G->pos)); - return 1; - l877:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseDd", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenDd(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenDd")); if (!yymatchChar(G, '<')) goto l880; if (!yy_Spnl(G)) { goto l880; } - { int yypos881= G->pos, yythunkpos881= G->thunkpos; if (!yymatchString(G, "dd")) goto l882; goto l881; - l882:; G->pos= yypos881; G->thunkpos= yythunkpos881; if (!yymatchString(G, "DD")) goto l880; - } - l881:; if (!yy_Spnl(G)) { goto l880; } - l883:; - { int yypos884= G->pos, yythunkpos884= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l884; } goto l883; - l884:; G->pos= yypos884; G->thunkpos= yythunkpos884; - } if (!yymatchChar(G, '>')) goto l880; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenDd", G->buf+G->pos)); - return 1; - l880:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenDd", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockUl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockUl")); if (!yy_HtmlBlockOpenUl(G)) { goto l885; } - l886:; - { int yypos887= G->pos, yythunkpos887= G->thunkpos; - { int yypos888= G->pos, yythunkpos888= G->thunkpos; if (!yy_HtmlBlockUl(G)) { goto l889; } goto l888; - l889:; G->pos= yypos888; G->thunkpos= yythunkpos888; - { int yypos890= G->pos, yythunkpos890= G->thunkpos; if (!yy_HtmlBlockCloseUl(G)) { goto l890; } goto l887; - l890:; G->pos= yypos890; G->thunkpos= yythunkpos890; - } if (!yymatchDot(G)) goto l887; - } - l888:; goto l886; - l887:; G->pos= yypos887; G->thunkpos= yythunkpos887; - } if (!yy_HtmlBlockCloseUl(G)) { goto l885; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockUl", G->buf+G->pos)); - return 1; - l885:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockUl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseUl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseUl")); if (!yymatchChar(G, '<')) goto l891; if (!yy_Spnl(G)) { goto l891; } if (!yymatchChar(G, '/')) goto l891; - { int yypos892= G->pos, yythunkpos892= G->thunkpos; if (!yymatchString(G, "ul")) goto l893; goto l892; - l893:; G->pos= yypos892; G->thunkpos= yythunkpos892; if (!yymatchString(G, "UL")) goto l891; - } - l892:; if (!yy_Spnl(G)) { goto l891; } if (!yymatchChar(G, '>')) goto l891; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseUl", G->buf+G->pos)); - return 1; - l891:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseUl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenUl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenUl")); if (!yymatchChar(G, '<')) goto l894; if (!yy_Spnl(G)) { goto l894; } - { int yypos895= G->pos, yythunkpos895= G->thunkpos; if (!yymatchString(G, "ul")) goto l896; goto l895; - l896:; G->pos= yypos895; G->thunkpos= yythunkpos895; if (!yymatchString(G, "UL")) goto l894; - } - l895:; if (!yy_Spnl(G)) { goto l894; } - l897:; - { int yypos898= G->pos, yythunkpos898= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l898; } goto l897; - l898:; G->pos= yypos898; G->thunkpos= yythunkpos898; - } if (!yymatchChar(G, '>')) goto l894; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenUl", G->buf+G->pos)); - return 1; - l894:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenUl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockTable(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockTable")); if (!yy_HtmlBlockOpenTable(G)) { goto l899; } - l900:; - { int yypos901= G->pos, yythunkpos901= G->thunkpos; - { int yypos902= G->pos, yythunkpos902= G->thunkpos; if (!yy_HtmlBlockTable(G)) { goto l903; } goto l902; - l903:; G->pos= yypos902; G->thunkpos= yythunkpos902; - { int yypos904= G->pos, yythunkpos904= G->thunkpos; if (!yy_HtmlBlockCloseTable(G)) { goto l904; } goto l901; - l904:; G->pos= yypos904; G->thunkpos= yythunkpos904; - } if (!yymatchDot(G)) goto l901; - } - l902:; goto l900; - l901:; G->pos= yypos901; G->thunkpos= yythunkpos901; - } if (!yy_HtmlBlockCloseTable(G)) { goto l899; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTable", G->buf+G->pos)); - return 1; - l899:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTable", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseTable(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseTable")); if (!yymatchChar(G, '<')) goto l905; if (!yy_Spnl(G)) { goto l905; } if (!yymatchChar(G, '/')) goto l905; - { int yypos906= G->pos, yythunkpos906= G->thunkpos; if (!yymatchString(G, "table")) goto l907; goto l906; - l907:; G->pos= yypos906; G->thunkpos= yythunkpos906; if (!yymatchString(G, "TABLE")) goto l905; - } - l906:; if (!yy_Spnl(G)) { goto l905; } if (!yymatchChar(G, '>')) goto l905; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTable", G->buf+G->pos)); - return 1; - l905:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTable", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenTable(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenTable")); if (!yymatchChar(G, '<')) goto l908; if (!yy_Spnl(G)) { goto l908; } - { int yypos909= G->pos, yythunkpos909= G->thunkpos; if (!yymatchString(G, "table")) goto l910; goto l909; - l910:; G->pos= yypos909; G->thunkpos= yythunkpos909; if (!yymatchString(G, "TABLE")) goto l908; - } - l909:; if (!yy_Spnl(G)) { goto l908; } - l911:; - { int yypos912= G->pos, yythunkpos912= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l912; } goto l911; - l912:; G->pos= yypos912; G->thunkpos= yythunkpos912; - } if (!yymatchChar(G, '>')) goto l908; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTable", G->buf+G->pos)); - return 1; - l908:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTable", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockPre(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockPre")); if (!yy_HtmlBlockOpenPre(G)) { goto l913; } - l914:; - { int yypos915= G->pos, yythunkpos915= G->thunkpos; - { int yypos916= G->pos, yythunkpos916= G->thunkpos; if (!yy_HtmlBlockPre(G)) { goto l917; } goto l916; - l917:; G->pos= yypos916; G->thunkpos= yythunkpos916; - { int yypos918= G->pos, yythunkpos918= G->thunkpos; if (!yy_HtmlBlockClosePre(G)) { goto l918; } goto l915; - l918:; G->pos= yypos918; G->thunkpos= yythunkpos918; - } if (!yymatchDot(G)) goto l915; - } - l916:; goto l914; - l915:; G->pos= yypos915; G->thunkpos= yythunkpos915; - } if (!yy_HtmlBlockClosePre(G)) { goto l913; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockPre", G->buf+G->pos)); - return 1; - l913:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockPre", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockClosePre(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockClosePre")); if (!yymatchChar(G, '<')) goto l919; if (!yy_Spnl(G)) { goto l919; } if (!yymatchChar(G, '/')) goto l919; - { int yypos920= G->pos, yythunkpos920= G->thunkpos; if (!yymatchString(G, "pre")) goto l921; goto l920; - l921:; G->pos= yypos920; G->thunkpos= yythunkpos920; if (!yymatchString(G, "PRE")) goto l919; - } - l920:; if (!yy_Spnl(G)) { goto l919; } if (!yymatchChar(G, '>')) goto l919; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockClosePre", G->buf+G->pos)); - return 1; - l919:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockClosePre", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenPre(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenPre")); if (!yymatchChar(G, '<')) goto l922; if (!yy_Spnl(G)) { goto l922; } - { int yypos923= G->pos, yythunkpos923= G->thunkpos; if (!yymatchString(G, "pre")) goto l924; goto l923; - l924:; G->pos= yypos923; G->thunkpos= yythunkpos923; if (!yymatchString(G, "PRE")) goto l922; - } - l923:; if (!yy_Spnl(G)) { goto l922; } - l925:; - { int yypos926= G->pos, yythunkpos926= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l926; } goto l925; - l926:; G->pos= yypos926; G->thunkpos= yythunkpos926; - } if (!yymatchChar(G, '>')) goto l922; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenPre", G->buf+G->pos)); - return 1; - l922:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenPre", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockP(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockP")); if (!yy_HtmlBlockOpenP(G)) { goto l927; } - l928:; - { int yypos929= G->pos, yythunkpos929= G->thunkpos; - { int yypos930= G->pos, yythunkpos930= G->thunkpos; if (!yy_HtmlBlockP(G)) { goto l931; } goto l930; - l931:; G->pos= yypos930; G->thunkpos= yythunkpos930; - { int yypos932= G->pos, yythunkpos932= G->thunkpos; if (!yy_HtmlBlockCloseP(G)) { goto l932; } goto l929; - l932:; G->pos= yypos932; G->thunkpos= yythunkpos932; - } if (!yymatchDot(G)) goto l929; - } - l930:; goto l928; - l929:; G->pos= yypos929; G->thunkpos= yythunkpos929; - } if (!yy_HtmlBlockCloseP(G)) { goto l927; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockP", G->buf+G->pos)); - return 1; - l927:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockP", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseP(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseP")); if (!yymatchChar(G, '<')) goto l933; if (!yy_Spnl(G)) { goto l933; } if (!yymatchChar(G, '/')) goto l933; - { int yypos934= G->pos, yythunkpos934= G->thunkpos; if (!yymatchChar(G, 'p')) goto l935; goto l934; - l935:; G->pos= yypos934; G->thunkpos= yythunkpos934; if (!yymatchChar(G, 'P')) goto l933; - } - l934:; if (!yy_Spnl(G)) { goto l933; } if (!yymatchChar(G, '>')) goto l933; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseP", G->buf+G->pos)); - return 1; - l933:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseP", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenP(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenP")); if (!yymatchChar(G, '<')) goto l936; if (!yy_Spnl(G)) { goto l936; } - { int yypos937= G->pos, yythunkpos937= G->thunkpos; if (!yymatchChar(G, 'p')) goto l938; goto l937; - l938:; G->pos= yypos937; G->thunkpos= yythunkpos937; if (!yymatchChar(G, 'P')) goto l936; - } - l937:; if (!yy_Spnl(G)) { goto l936; } - l939:; - { int yypos940= G->pos, yythunkpos940= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l940; } goto l939; - l940:; G->pos= yypos940; G->thunkpos= yythunkpos940; - } if (!yymatchChar(G, '>')) goto l936; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenP", G->buf+G->pos)); - return 1; - l936:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenP", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOl")); if (!yy_HtmlBlockOpenOl(G)) { goto l941; } - l942:; - { int yypos943= G->pos, yythunkpos943= G->thunkpos; - { int yypos944= G->pos, yythunkpos944= G->thunkpos; if (!yy_HtmlBlockOl(G)) { goto l945; } goto l944; - l945:; G->pos= yypos944; G->thunkpos= yythunkpos944; - { int yypos946= G->pos, yythunkpos946= G->thunkpos; if (!yy_HtmlBlockCloseOl(G)) { goto l946; } goto l943; - l946:; G->pos= yypos946; G->thunkpos= yythunkpos946; - } if (!yymatchDot(G)) goto l943; - } - l944:; goto l942; - l943:; G->pos= yypos943; G->thunkpos= yythunkpos943; - } if (!yy_HtmlBlockCloseOl(G)) { goto l941; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOl", G->buf+G->pos)); - return 1; - l941:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseOl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseOl")); if (!yymatchChar(G, '<')) goto l947; if (!yy_Spnl(G)) { goto l947; } if (!yymatchChar(G, '/')) goto l947; - { int yypos948= G->pos, yythunkpos948= G->thunkpos; if (!yymatchString(G, "ol")) goto l949; goto l948; - l949:; G->pos= yypos948; G->thunkpos= yythunkpos948; if (!yymatchString(G, "OL")) goto l947; - } - l948:; if (!yy_Spnl(G)) { goto l947; } if (!yymatchChar(G, '>')) goto l947; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseOl", G->buf+G->pos)); - return 1; - l947:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseOl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenOl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenOl")); if (!yymatchChar(G, '<')) goto l950; if (!yy_Spnl(G)) { goto l950; } - { int yypos951= G->pos, yythunkpos951= G->thunkpos; if (!yymatchString(G, "ol")) goto l952; goto l951; - l952:; G->pos= yypos951; G->thunkpos= yythunkpos951; if (!yymatchString(G, "OL")) goto l950; - } - l951:; if (!yy_Spnl(G)) { goto l950; } - l953:; - { int yypos954= G->pos, yythunkpos954= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l954; } goto l953; - l954:; G->pos= yypos954; G->thunkpos= yythunkpos954; - } if (!yymatchChar(G, '>')) goto l950; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenOl", G->buf+G->pos)); - return 1; - l950:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenOl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockNoscript(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockNoscript")); if (!yy_HtmlBlockOpenNoscript(G)) { goto l955; } - l956:; - { int yypos957= G->pos, yythunkpos957= G->thunkpos; - { int yypos958= G->pos, yythunkpos958= G->thunkpos; if (!yy_HtmlBlockNoscript(G)) { goto l959; } goto l958; - l959:; G->pos= yypos958; G->thunkpos= yythunkpos958; - { int yypos960= G->pos, yythunkpos960= G->thunkpos; if (!yy_HtmlBlockCloseNoscript(G)) { goto l960; } goto l957; - l960:; G->pos= yypos960; G->thunkpos= yythunkpos960; - } if (!yymatchDot(G)) goto l957; - } - l958:; goto l956; - l957:; G->pos= yypos957; G->thunkpos= yythunkpos957; - } if (!yy_HtmlBlockCloseNoscript(G)) { goto l955; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockNoscript", G->buf+G->pos)); - return 1; - l955:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockNoscript", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseNoscript(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseNoscript")); if (!yymatchChar(G, '<')) goto l961; if (!yy_Spnl(G)) { goto l961; } if (!yymatchChar(G, '/')) goto l961; - { int yypos962= G->pos, yythunkpos962= G->thunkpos; if (!yymatchString(G, "noscript")) goto l963; goto l962; - l963:; G->pos= yypos962; G->thunkpos= yythunkpos962; if (!yymatchString(G, "NOSCRIPT")) goto l961; - } - l962:; if (!yy_Spnl(G)) { goto l961; } if (!yymatchChar(G, '>')) goto l961; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseNoscript", G->buf+G->pos)); - return 1; - l961:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseNoscript", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenNoscript(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenNoscript")); if (!yymatchChar(G, '<')) goto l964; if (!yy_Spnl(G)) { goto l964; } - { int yypos965= G->pos, yythunkpos965= G->thunkpos; if (!yymatchString(G, "noscript")) goto l966; goto l965; - l966:; G->pos= yypos965; G->thunkpos= yythunkpos965; if (!yymatchString(G, "NOSCRIPT")) goto l964; - } - l965:; if (!yy_Spnl(G)) { goto l964; } - l967:; - { int yypos968= G->pos, yythunkpos968= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l968; } goto l967; - l968:; G->pos= yypos968; G->thunkpos= yythunkpos968; - } if (!yymatchChar(G, '>')) goto l964; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenNoscript", G->buf+G->pos)); - return 1; - l964:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenNoscript", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockNoframes(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockNoframes")); if (!yy_HtmlBlockOpenNoframes(G)) { goto l969; } - l970:; - { int yypos971= G->pos, yythunkpos971= G->thunkpos; - { int yypos972= G->pos, yythunkpos972= G->thunkpos; if (!yy_HtmlBlockNoframes(G)) { goto l973; } goto l972; - l973:; G->pos= yypos972; G->thunkpos= yythunkpos972; - { int yypos974= G->pos, yythunkpos974= G->thunkpos; if (!yy_HtmlBlockCloseNoframes(G)) { goto l974; } goto l971; - l974:; G->pos= yypos974; G->thunkpos= yythunkpos974; - } if (!yymatchDot(G)) goto l971; - } - l972:; goto l970; - l971:; G->pos= yypos971; G->thunkpos= yythunkpos971; - } if (!yy_HtmlBlockCloseNoframes(G)) { goto l969; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockNoframes", G->buf+G->pos)); - return 1; - l969:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockNoframes", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseNoframes(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseNoframes")); if (!yymatchChar(G, '<')) goto l975; if (!yy_Spnl(G)) { goto l975; } if (!yymatchChar(G, '/')) goto l975; - { int yypos976= G->pos, yythunkpos976= G->thunkpos; if (!yymatchString(G, "noframes")) goto l977; goto l976; - l977:; G->pos= yypos976; G->thunkpos= yythunkpos976; if (!yymatchString(G, "NOFRAMES")) goto l975; - } - l976:; if (!yy_Spnl(G)) { goto l975; } if (!yymatchChar(G, '>')) goto l975; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseNoframes", G->buf+G->pos)); - return 1; - l975:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseNoframes", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenNoframes(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenNoframes")); if (!yymatchChar(G, '<')) goto l978; if (!yy_Spnl(G)) { goto l978; } - { int yypos979= G->pos, yythunkpos979= G->thunkpos; if (!yymatchString(G, "noframes")) goto l980; goto l979; - l980:; G->pos= yypos979; G->thunkpos= yythunkpos979; if (!yymatchString(G, "NOFRAMES")) goto l978; - } - l979:; if (!yy_Spnl(G)) { goto l978; } - l981:; - { int yypos982= G->pos, yythunkpos982= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l982; } goto l981; - l982:; G->pos= yypos982; G->thunkpos= yythunkpos982; - } if (!yymatchChar(G, '>')) goto l978; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenNoframes", G->buf+G->pos)); - return 1; - l978:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenNoframes", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockMenu(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockMenu")); if (!yy_HtmlBlockOpenMenu(G)) { goto l983; } - l984:; - { int yypos985= G->pos, yythunkpos985= G->thunkpos; - { int yypos986= G->pos, yythunkpos986= G->thunkpos; if (!yy_HtmlBlockMenu(G)) { goto l987; } goto l986; - l987:; G->pos= yypos986; G->thunkpos= yythunkpos986; - { int yypos988= G->pos, yythunkpos988= G->thunkpos; if (!yy_HtmlBlockCloseMenu(G)) { goto l988; } goto l985; - l988:; G->pos= yypos988; G->thunkpos= yythunkpos988; - } if (!yymatchDot(G)) goto l985; - } - l986:; goto l984; - l985:; G->pos= yypos985; G->thunkpos= yythunkpos985; - } if (!yy_HtmlBlockCloseMenu(G)) { goto l983; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockMenu", G->buf+G->pos)); - return 1; - l983:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockMenu", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseMenu(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseMenu")); if (!yymatchChar(G, '<')) goto l989; if (!yy_Spnl(G)) { goto l989; } if (!yymatchChar(G, '/')) goto l989; - { int yypos990= G->pos, yythunkpos990= G->thunkpos; if (!yymatchString(G, "menu")) goto l991; goto l990; - l991:; G->pos= yypos990; G->thunkpos= yythunkpos990; if (!yymatchString(G, "MENU")) goto l989; - } - l990:; if (!yy_Spnl(G)) { goto l989; } if (!yymatchChar(G, '>')) goto l989; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseMenu", G->buf+G->pos)); - return 1; - l989:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseMenu", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenMenu(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenMenu")); if (!yymatchChar(G, '<')) goto l992; if (!yy_Spnl(G)) { goto l992; } - { int yypos993= G->pos, yythunkpos993= G->thunkpos; if (!yymatchString(G, "menu")) goto l994; goto l993; - l994:; G->pos= yypos993; G->thunkpos= yythunkpos993; if (!yymatchString(G, "MENU")) goto l992; - } - l993:; if (!yy_Spnl(G)) { goto l992; } - l995:; - { int yypos996= G->pos, yythunkpos996= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l996; } goto l995; - l996:; G->pos= yypos996; G->thunkpos= yythunkpos996; - } if (!yymatchChar(G, '>')) goto l992; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenMenu", G->buf+G->pos)); - return 1; - l992:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenMenu", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockH6(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "HtmlBlockH6")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l997; if (!yy_LocMarker(G)) { goto l997; } yyDo(G, yySet, -1, 0); if (!yy_HtmlBlockOpenH6(G)) { goto l997; } - l998:; - { int yypos999= G->pos, yythunkpos999= G->thunkpos; - { int yypos1000= G->pos, yythunkpos1000= G->thunkpos; if (!yy_HtmlBlockH6(G)) { goto l1001; } goto l1000; - l1001:; G->pos= yypos1000; G->thunkpos= yythunkpos1000; - { int yypos1002= G->pos, yythunkpos1002= G->thunkpos; if (!yy_HtmlBlockCloseH6(G)) { goto l1002; } goto l999; - l1002:; G->pos= yypos1002; G->thunkpos= yythunkpos1002; - } if (!yymatchDot(G)) goto l999; - } - l1000:; goto l998; - l999:; G->pos= yypos999; G->thunkpos= yythunkpos999; - } if (!yy_HtmlBlockCloseH6(G)) { goto l997; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l997; yyDo(G, yy_1_HtmlBlockH6, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH6", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l997:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH6", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseH6(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseH6")); if (!yymatchChar(G, '<')) goto l1003; if (!yy_Spnl(G)) { goto l1003; } if (!yymatchChar(G, '/')) goto l1003; - { int yypos1004= G->pos, yythunkpos1004= G->thunkpos; if (!yymatchString(G, "h6")) goto l1005; goto l1004; - l1005:; G->pos= yypos1004; G->thunkpos= yythunkpos1004; if (!yymatchString(G, "H6")) goto l1003; - } - l1004:; if (!yy_Spnl(G)) { goto l1003; } if (!yymatchChar(G, '>')) goto l1003; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH6", G->buf+G->pos)); - return 1; - l1003:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH6", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenH6(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenH6")); if (!yymatchChar(G, '<')) goto l1006; if (!yy_Spnl(G)) { goto l1006; } - { int yypos1007= G->pos, yythunkpos1007= G->thunkpos; if (!yymatchString(G, "h6")) goto l1008; goto l1007; - l1008:; G->pos= yypos1007; G->thunkpos= yythunkpos1007; if (!yymatchString(G, "H6")) goto l1006; - } - l1007:; if (!yy_Spnl(G)) { goto l1006; } - l1009:; - { int yypos1010= G->pos, yythunkpos1010= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1010; } goto l1009; - l1010:; G->pos= yypos1010; G->thunkpos= yythunkpos1010; - } if (!yymatchChar(G, '>')) goto l1006; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH6", G->buf+G->pos)); - return 1; - l1006:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH6", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockH5(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "HtmlBlockH5")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1011; if (!yy_LocMarker(G)) { goto l1011; } yyDo(G, yySet, -1, 0); if (!yy_HtmlBlockOpenH5(G)) { goto l1011; } - l1012:; - { int yypos1013= G->pos, yythunkpos1013= G->thunkpos; - { int yypos1014= G->pos, yythunkpos1014= G->thunkpos; if (!yy_HtmlBlockH5(G)) { goto l1015; } goto l1014; - l1015:; G->pos= yypos1014; G->thunkpos= yythunkpos1014; - { int yypos1016= G->pos, yythunkpos1016= G->thunkpos; if (!yy_HtmlBlockCloseH5(G)) { goto l1016; } goto l1013; - l1016:; G->pos= yypos1016; G->thunkpos= yythunkpos1016; - } if (!yymatchDot(G)) goto l1013; - } - l1014:; goto l1012; - l1013:; G->pos= yypos1013; G->thunkpos= yythunkpos1013; - } if (!yy_HtmlBlockCloseH5(G)) { goto l1011; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1011; yyDo(G, yy_1_HtmlBlockH5, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH5", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1011:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH5", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseH5(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseH5")); if (!yymatchChar(G, '<')) goto l1017; if (!yy_Spnl(G)) { goto l1017; } if (!yymatchChar(G, '/')) goto l1017; - { int yypos1018= G->pos, yythunkpos1018= G->thunkpos; if (!yymatchString(G, "h5")) goto l1019; goto l1018; - l1019:; G->pos= yypos1018; G->thunkpos= yythunkpos1018; if (!yymatchString(G, "H5")) goto l1017; - } - l1018:; if (!yy_Spnl(G)) { goto l1017; } if (!yymatchChar(G, '>')) goto l1017; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH5", G->buf+G->pos)); - return 1; - l1017:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH5", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenH5(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenH5")); if (!yymatchChar(G, '<')) goto l1020; if (!yy_Spnl(G)) { goto l1020; } - { int yypos1021= G->pos, yythunkpos1021= G->thunkpos; if (!yymatchString(G, "h5")) goto l1022; goto l1021; - l1022:; G->pos= yypos1021; G->thunkpos= yythunkpos1021; if (!yymatchString(G, "H5")) goto l1020; - } - l1021:; if (!yy_Spnl(G)) { goto l1020; } - l1023:; - { int yypos1024= G->pos, yythunkpos1024= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1024; } goto l1023; - l1024:; G->pos= yypos1024; G->thunkpos= yythunkpos1024; - } if (!yymatchChar(G, '>')) goto l1020; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH5", G->buf+G->pos)); - return 1; - l1020:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH5", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockH4(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "HtmlBlockH4")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1025; if (!yy_LocMarker(G)) { goto l1025; } yyDo(G, yySet, -1, 0); if (!yy_HtmlBlockOpenH4(G)) { goto l1025; } - l1026:; - { int yypos1027= G->pos, yythunkpos1027= G->thunkpos; - { int yypos1028= G->pos, yythunkpos1028= G->thunkpos; if (!yy_HtmlBlockH4(G)) { goto l1029; } goto l1028; - l1029:; G->pos= yypos1028; G->thunkpos= yythunkpos1028; - { int yypos1030= G->pos, yythunkpos1030= G->thunkpos; if (!yy_HtmlBlockCloseH4(G)) { goto l1030; } goto l1027; - l1030:; G->pos= yypos1030; G->thunkpos= yythunkpos1030; - } if (!yymatchDot(G)) goto l1027; - } - l1028:; goto l1026; - l1027:; G->pos= yypos1027; G->thunkpos= yythunkpos1027; - } if (!yy_HtmlBlockCloseH4(G)) { goto l1025; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1025; yyDo(G, yy_1_HtmlBlockH4, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH4", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1025:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH4", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseH4(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseH4")); if (!yymatchChar(G, '<')) goto l1031; if (!yy_Spnl(G)) { goto l1031; } if (!yymatchChar(G, '/')) goto l1031; - { int yypos1032= G->pos, yythunkpos1032= G->thunkpos; if (!yymatchString(G, "h4")) goto l1033; goto l1032; - l1033:; G->pos= yypos1032; G->thunkpos= yythunkpos1032; if (!yymatchString(G, "H4")) goto l1031; - } - l1032:; if (!yy_Spnl(G)) { goto l1031; } if (!yymatchChar(G, '>')) goto l1031; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH4", G->buf+G->pos)); - return 1; - l1031:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH4", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenH4(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenH4")); if (!yymatchChar(G, '<')) goto l1034; if (!yy_Spnl(G)) { goto l1034; } - { int yypos1035= G->pos, yythunkpos1035= G->thunkpos; if (!yymatchString(G, "h4")) goto l1036; goto l1035; - l1036:; G->pos= yypos1035; G->thunkpos= yythunkpos1035; if (!yymatchString(G, "H4")) goto l1034; - } - l1035:; if (!yy_Spnl(G)) { goto l1034; } - l1037:; - { int yypos1038= G->pos, yythunkpos1038= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1038; } goto l1037; - l1038:; G->pos= yypos1038; G->thunkpos= yythunkpos1038; - } if (!yymatchChar(G, '>')) goto l1034; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH4", G->buf+G->pos)); - return 1; - l1034:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH4", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockH3(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "HtmlBlockH3")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1039; if (!yy_LocMarker(G)) { goto l1039; } yyDo(G, yySet, -1, 0); if (!yy_HtmlBlockOpenH3(G)) { goto l1039; } - l1040:; - { int yypos1041= G->pos, yythunkpos1041= G->thunkpos; - { int yypos1042= G->pos, yythunkpos1042= G->thunkpos; if (!yy_HtmlBlockH3(G)) { goto l1043; } goto l1042; - l1043:; G->pos= yypos1042; G->thunkpos= yythunkpos1042; - { int yypos1044= G->pos, yythunkpos1044= G->thunkpos; if (!yy_HtmlBlockCloseH3(G)) { goto l1044; } goto l1041; - l1044:; G->pos= yypos1044; G->thunkpos= yythunkpos1044; - } if (!yymatchDot(G)) goto l1041; - } - l1042:; goto l1040; - l1041:; G->pos= yypos1041; G->thunkpos= yythunkpos1041; - } if (!yy_HtmlBlockCloseH3(G)) { goto l1039; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1039; yyDo(G, yy_1_HtmlBlockH3, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH3", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1039:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH3", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseH3(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseH3")); if (!yymatchChar(G, '<')) goto l1045; if (!yy_Spnl(G)) { goto l1045; } if (!yymatchChar(G, '/')) goto l1045; - { int yypos1046= G->pos, yythunkpos1046= G->thunkpos; if (!yymatchString(G, "h3")) goto l1047; goto l1046; - l1047:; G->pos= yypos1046; G->thunkpos= yythunkpos1046; if (!yymatchString(G, "H3")) goto l1045; - } - l1046:; if (!yy_Spnl(G)) { goto l1045; } if (!yymatchChar(G, '>')) goto l1045; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH3", G->buf+G->pos)); - return 1; - l1045:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH3", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenH3(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenH3")); if (!yymatchChar(G, '<')) goto l1048; if (!yy_Spnl(G)) { goto l1048; } - { int yypos1049= G->pos, yythunkpos1049= G->thunkpos; if (!yymatchString(G, "h3")) goto l1050; goto l1049; - l1050:; G->pos= yypos1049; G->thunkpos= yythunkpos1049; if (!yymatchString(G, "H3")) goto l1048; - } - l1049:; if (!yy_Spnl(G)) { goto l1048; } - l1051:; - { int yypos1052= G->pos, yythunkpos1052= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1052; } goto l1051; - l1052:; G->pos= yypos1052; G->thunkpos= yythunkpos1052; - } if (!yymatchChar(G, '>')) goto l1048; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH3", G->buf+G->pos)); - return 1; - l1048:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH3", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockH2(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "HtmlBlockH2")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1053; if (!yy_LocMarker(G)) { goto l1053; } yyDo(G, yySet, -1, 0); if (!yy_HtmlBlockOpenH2(G)) { goto l1053; } - l1054:; - { int yypos1055= G->pos, yythunkpos1055= G->thunkpos; - { int yypos1056= G->pos, yythunkpos1056= G->thunkpos; if (!yy_HtmlBlockH2(G)) { goto l1057; } goto l1056; - l1057:; G->pos= yypos1056; G->thunkpos= yythunkpos1056; - { int yypos1058= G->pos, yythunkpos1058= G->thunkpos; if (!yy_HtmlBlockCloseH2(G)) { goto l1058; } goto l1055; - l1058:; G->pos= yypos1058; G->thunkpos= yythunkpos1058; - } if (!yymatchDot(G)) goto l1055; - } - l1056:; goto l1054; - l1055:; G->pos= yypos1055; G->thunkpos= yythunkpos1055; - } if (!yy_HtmlBlockCloseH2(G)) { goto l1053; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1053; yyDo(G, yy_1_HtmlBlockH2, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH2", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1053:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH2", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseH2(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseH2")); if (!yymatchChar(G, '<')) goto l1059; if (!yy_Spnl(G)) { goto l1059; } if (!yymatchChar(G, '/')) goto l1059; - { int yypos1060= G->pos, yythunkpos1060= G->thunkpos; if (!yymatchString(G, "h2")) goto l1061; goto l1060; - l1061:; G->pos= yypos1060; G->thunkpos= yythunkpos1060; if (!yymatchString(G, "H2")) goto l1059; - } - l1060:; if (!yy_Spnl(G)) { goto l1059; } if (!yymatchChar(G, '>')) goto l1059; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH2", G->buf+G->pos)); - return 1; - l1059:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH2", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenH2(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenH2")); if (!yymatchChar(G, '<')) goto l1062; if (!yy_Spnl(G)) { goto l1062; } - { int yypos1063= G->pos, yythunkpos1063= G->thunkpos; if (!yymatchString(G, "h2")) goto l1064; goto l1063; - l1064:; G->pos= yypos1063; G->thunkpos= yythunkpos1063; if (!yymatchString(G, "H2")) goto l1062; - } - l1063:; if (!yy_Spnl(G)) { goto l1062; } - l1065:; - { int yypos1066= G->pos, yythunkpos1066= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1066; } goto l1065; - l1066:; G->pos= yypos1066; G->thunkpos= yythunkpos1066; - } if (!yymatchChar(G, '>')) goto l1062; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH2", G->buf+G->pos)); - return 1; - l1062:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH2", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockH1(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "HtmlBlockH1")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1067; if (!yy_LocMarker(G)) { goto l1067; } yyDo(G, yySet, -1, 0); if (!yy_HtmlBlockOpenH1(G)) { goto l1067; } - l1068:; - { int yypos1069= G->pos, yythunkpos1069= G->thunkpos; - { int yypos1070= G->pos, yythunkpos1070= G->thunkpos; if (!yy_HtmlBlockH1(G)) { goto l1071; } goto l1070; - l1071:; G->pos= yypos1070; G->thunkpos= yythunkpos1070; - { int yypos1072= G->pos, yythunkpos1072= G->thunkpos; if (!yy_HtmlBlockCloseH1(G)) { goto l1072; } goto l1069; - l1072:; G->pos= yypos1072; G->thunkpos= yythunkpos1072; - } if (!yymatchDot(G)) goto l1069; - } - l1070:; goto l1068; - l1069:; G->pos= yypos1069; G->thunkpos= yythunkpos1069; - } if (!yy_HtmlBlockCloseH1(G)) { goto l1067; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1067; yyDo(G, yy_1_HtmlBlockH1, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH1", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1067:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH1", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseH1(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseH1")); if (!yymatchChar(G, '<')) goto l1073; if (!yy_Spnl(G)) { goto l1073; } if (!yymatchChar(G, '/')) goto l1073; - { int yypos1074= G->pos, yythunkpos1074= G->thunkpos; if (!yymatchString(G, "h1")) goto l1075; goto l1074; - l1075:; G->pos= yypos1074; G->thunkpos= yythunkpos1074; if (!yymatchString(G, "H1")) goto l1073; - } - l1074:; if (!yy_Spnl(G)) { goto l1073; } if (!yymatchChar(G, '>')) goto l1073; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH1", G->buf+G->pos)); - return 1; - l1073:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH1", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenH1(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenH1")); if (!yymatchChar(G, '<')) goto l1076; if (!yy_Spnl(G)) { goto l1076; } - { int yypos1077= G->pos, yythunkpos1077= G->thunkpos; if (!yymatchString(G, "h1")) goto l1078; goto l1077; - l1078:; G->pos= yypos1077; G->thunkpos= yythunkpos1077; if (!yymatchString(G, "H1")) goto l1076; - } - l1077:; if (!yy_Spnl(G)) { goto l1076; } - l1079:; - { int yypos1080= G->pos, yythunkpos1080= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1080; } goto l1079; - l1080:; G->pos= yypos1080; G->thunkpos= yythunkpos1080; - } if (!yymatchChar(G, '>')) goto l1076; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH1", G->buf+G->pos)); - return 1; - l1076:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH1", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockForm(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockForm")); if (!yy_HtmlBlockOpenForm(G)) { goto l1081; } - l1082:; - { int yypos1083= G->pos, yythunkpos1083= G->thunkpos; - { int yypos1084= G->pos, yythunkpos1084= G->thunkpos; if (!yy_HtmlBlockForm(G)) { goto l1085; } goto l1084; - l1085:; G->pos= yypos1084; G->thunkpos= yythunkpos1084; - { int yypos1086= G->pos, yythunkpos1086= G->thunkpos; if (!yy_HtmlBlockCloseForm(G)) { goto l1086; } goto l1083; - l1086:; G->pos= yypos1086; G->thunkpos= yythunkpos1086; - } if (!yymatchDot(G)) goto l1083; - } - l1084:; goto l1082; - l1083:; G->pos= yypos1083; G->thunkpos= yythunkpos1083; - } if (!yy_HtmlBlockCloseForm(G)) { goto l1081; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockForm", G->buf+G->pos)); - return 1; - l1081:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockForm", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseForm(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseForm")); if (!yymatchChar(G, '<')) goto l1087; if (!yy_Spnl(G)) { goto l1087; } if (!yymatchChar(G, '/')) goto l1087; - { int yypos1088= G->pos, yythunkpos1088= G->thunkpos; if (!yymatchString(G, "form")) goto l1089; goto l1088; - l1089:; G->pos= yypos1088; G->thunkpos= yythunkpos1088; if (!yymatchString(G, "FORM")) goto l1087; - } - l1088:; if (!yy_Spnl(G)) { goto l1087; } if (!yymatchChar(G, '>')) goto l1087; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseForm", G->buf+G->pos)); - return 1; - l1087:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseForm", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenForm(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenForm")); if (!yymatchChar(G, '<')) goto l1090; if (!yy_Spnl(G)) { goto l1090; } - { int yypos1091= G->pos, yythunkpos1091= G->thunkpos; if (!yymatchString(G, "form")) goto l1092; goto l1091; - l1092:; G->pos= yypos1091; G->thunkpos= yythunkpos1091; if (!yymatchString(G, "FORM")) goto l1090; - } - l1091:; if (!yy_Spnl(G)) { goto l1090; } - l1093:; - { int yypos1094= G->pos, yythunkpos1094= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1094; } goto l1093; - l1094:; G->pos= yypos1094; G->thunkpos= yythunkpos1094; - } if (!yymatchChar(G, '>')) goto l1090; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenForm", G->buf+G->pos)); - return 1; - l1090:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenForm", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockFieldset(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockFieldset")); if (!yy_HtmlBlockOpenFieldset(G)) { goto l1095; } - l1096:; - { int yypos1097= G->pos, yythunkpos1097= G->thunkpos; - { int yypos1098= G->pos, yythunkpos1098= G->thunkpos; if (!yy_HtmlBlockFieldset(G)) { goto l1099; } goto l1098; - l1099:; G->pos= yypos1098; G->thunkpos= yythunkpos1098; - { int yypos1100= G->pos, yythunkpos1100= G->thunkpos; if (!yy_HtmlBlockCloseFieldset(G)) { goto l1100; } goto l1097; - l1100:; G->pos= yypos1100; G->thunkpos= yythunkpos1100; - } if (!yymatchDot(G)) goto l1097; - } - l1098:; goto l1096; - l1097:; G->pos= yypos1097; G->thunkpos= yythunkpos1097; - } if (!yy_HtmlBlockCloseFieldset(G)) { goto l1095; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockFieldset", G->buf+G->pos)); - return 1; - l1095:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockFieldset", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseFieldset(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseFieldset")); if (!yymatchChar(G, '<')) goto l1101; if (!yy_Spnl(G)) { goto l1101; } if (!yymatchChar(G, '/')) goto l1101; - { int yypos1102= G->pos, yythunkpos1102= G->thunkpos; if (!yymatchString(G, "fieldset")) goto l1103; goto l1102; - l1103:; G->pos= yypos1102; G->thunkpos= yythunkpos1102; if (!yymatchString(G, "FIELDSET")) goto l1101; - } - l1102:; if (!yy_Spnl(G)) { goto l1101; } if (!yymatchChar(G, '>')) goto l1101; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseFieldset", G->buf+G->pos)); - return 1; - l1101:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseFieldset", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenFieldset(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenFieldset")); if (!yymatchChar(G, '<')) goto l1104; if (!yy_Spnl(G)) { goto l1104; } - { int yypos1105= G->pos, yythunkpos1105= G->thunkpos; if (!yymatchString(G, "fieldset")) goto l1106; goto l1105; - l1106:; G->pos= yypos1105; G->thunkpos= yythunkpos1105; if (!yymatchString(G, "FIELDSET")) goto l1104; - } - l1105:; if (!yy_Spnl(G)) { goto l1104; } - l1107:; - { int yypos1108= G->pos, yythunkpos1108= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1108; } goto l1107; - l1108:; G->pos= yypos1108; G->thunkpos= yythunkpos1108; - } if (!yymatchChar(G, '>')) goto l1104; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenFieldset", G->buf+G->pos)); - return 1; - l1104:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenFieldset", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockDl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockDl")); if (!yy_HtmlBlockOpenDl(G)) { goto l1109; } - l1110:; - { int yypos1111= G->pos, yythunkpos1111= G->thunkpos; - { int yypos1112= G->pos, yythunkpos1112= G->thunkpos; if (!yy_HtmlBlockDl(G)) { goto l1113; } goto l1112; - l1113:; G->pos= yypos1112; G->thunkpos= yythunkpos1112; - { int yypos1114= G->pos, yythunkpos1114= G->thunkpos; if (!yy_HtmlBlockCloseDl(G)) { goto l1114; } goto l1111; - l1114:; G->pos= yypos1114; G->thunkpos= yythunkpos1114; - } if (!yymatchDot(G)) goto l1111; - } - l1112:; goto l1110; - l1111:; G->pos= yypos1111; G->thunkpos= yythunkpos1111; - } if (!yy_HtmlBlockCloseDl(G)) { goto l1109; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockDl", G->buf+G->pos)); - return 1; - l1109:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockDl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseDl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseDl")); if (!yymatchChar(G, '<')) goto l1115; if (!yy_Spnl(G)) { goto l1115; } if (!yymatchChar(G, '/')) goto l1115; - { int yypos1116= G->pos, yythunkpos1116= G->thunkpos; if (!yymatchString(G, "dl")) goto l1117; goto l1116; - l1117:; G->pos= yypos1116; G->thunkpos= yythunkpos1116; if (!yymatchString(G, "DL")) goto l1115; - } - l1116:; if (!yy_Spnl(G)) { goto l1115; } if (!yymatchChar(G, '>')) goto l1115; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseDl", G->buf+G->pos)); - return 1; - l1115:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseDl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenDl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenDl")); if (!yymatchChar(G, '<')) goto l1118; if (!yy_Spnl(G)) { goto l1118; } - { int yypos1119= G->pos, yythunkpos1119= G->thunkpos; if (!yymatchString(G, "dl")) goto l1120; goto l1119; - l1120:; G->pos= yypos1119; G->thunkpos= yythunkpos1119; if (!yymatchString(G, "DL")) goto l1118; - } - l1119:; if (!yy_Spnl(G)) { goto l1118; } - l1121:; - { int yypos1122= G->pos, yythunkpos1122= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1122; } goto l1121; - l1122:; G->pos= yypos1122; G->thunkpos= yythunkpos1122; - } if (!yymatchChar(G, '>')) goto l1118; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenDl", G->buf+G->pos)); - return 1; - l1118:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenDl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockDiv(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockDiv")); if (!yy_HtmlBlockOpenDiv(G)) { goto l1123; } - l1124:; - { int yypos1125= G->pos, yythunkpos1125= G->thunkpos; - { int yypos1126= G->pos, yythunkpos1126= G->thunkpos; if (!yy_HtmlBlockDiv(G)) { goto l1127; } goto l1126; - l1127:; G->pos= yypos1126; G->thunkpos= yythunkpos1126; - { int yypos1128= G->pos, yythunkpos1128= G->thunkpos; if (!yy_HtmlBlockCloseDiv(G)) { goto l1128; } goto l1125; - l1128:; G->pos= yypos1128; G->thunkpos= yythunkpos1128; - } if (!yymatchDot(G)) goto l1125; - } - l1126:; goto l1124; - l1125:; G->pos= yypos1125; G->thunkpos= yythunkpos1125; - } if (!yy_HtmlBlockCloseDiv(G)) { goto l1123; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockDiv", G->buf+G->pos)); - return 1; - l1123:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockDiv", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseDiv(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseDiv")); if (!yymatchChar(G, '<')) goto l1129; if (!yy_Spnl(G)) { goto l1129; } if (!yymatchChar(G, '/')) goto l1129; - { int yypos1130= G->pos, yythunkpos1130= G->thunkpos; if (!yymatchString(G, "div")) goto l1131; goto l1130; - l1131:; G->pos= yypos1130; G->thunkpos= yythunkpos1130; if (!yymatchString(G, "DIV")) goto l1129; - } - l1130:; if (!yy_Spnl(G)) { goto l1129; } if (!yymatchChar(G, '>')) goto l1129; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseDiv", G->buf+G->pos)); - return 1; - l1129:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseDiv", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenDiv(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenDiv")); if (!yymatchChar(G, '<')) goto l1132; if (!yy_Spnl(G)) { goto l1132; } - { int yypos1133= G->pos, yythunkpos1133= G->thunkpos; if (!yymatchString(G, "div")) goto l1134; goto l1133; - l1134:; G->pos= yypos1133; G->thunkpos= yythunkpos1133; if (!yymatchString(G, "DIV")) goto l1132; - } - l1133:; if (!yy_Spnl(G)) { goto l1132; } - l1135:; - { int yypos1136= G->pos, yythunkpos1136= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1136; } goto l1135; - l1136:; G->pos= yypos1136; G->thunkpos= yythunkpos1136; - } if (!yymatchChar(G, '>')) goto l1132; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenDiv", G->buf+G->pos)); - return 1; - l1132:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenDiv", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockDir(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockDir")); if (!yy_HtmlBlockOpenDir(G)) { goto l1137; } - l1138:; - { int yypos1139= G->pos, yythunkpos1139= G->thunkpos; - { int yypos1140= G->pos, yythunkpos1140= G->thunkpos; if (!yy_HtmlBlockDir(G)) { goto l1141; } goto l1140; - l1141:; G->pos= yypos1140; G->thunkpos= yythunkpos1140; - { int yypos1142= G->pos, yythunkpos1142= G->thunkpos; if (!yy_HtmlBlockCloseDir(G)) { goto l1142; } goto l1139; - l1142:; G->pos= yypos1142; G->thunkpos= yythunkpos1142; - } if (!yymatchDot(G)) goto l1139; - } - l1140:; goto l1138; - l1139:; G->pos= yypos1139; G->thunkpos= yythunkpos1139; - } if (!yy_HtmlBlockCloseDir(G)) { goto l1137; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockDir", G->buf+G->pos)); - return 1; - l1137:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockDir", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseDir(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseDir")); if (!yymatchChar(G, '<')) goto l1143; if (!yy_Spnl(G)) { goto l1143; } if (!yymatchChar(G, '/')) goto l1143; - { int yypos1144= G->pos, yythunkpos1144= G->thunkpos; if (!yymatchString(G, "dir")) goto l1145; goto l1144; - l1145:; G->pos= yypos1144; G->thunkpos= yythunkpos1144; if (!yymatchString(G, "DIR")) goto l1143; - } - l1144:; if (!yy_Spnl(G)) { goto l1143; } if (!yymatchChar(G, '>')) goto l1143; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseDir", G->buf+G->pos)); - return 1; - l1143:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseDir", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenDir(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenDir")); if (!yymatchChar(G, '<')) goto l1146; if (!yy_Spnl(G)) { goto l1146; } - { int yypos1147= G->pos, yythunkpos1147= G->thunkpos; if (!yymatchString(G, "dir")) goto l1148; goto l1147; - l1148:; G->pos= yypos1147; G->thunkpos= yythunkpos1147; if (!yymatchString(G, "DIR")) goto l1146; - } - l1147:; if (!yy_Spnl(G)) { goto l1146; } - l1149:; - { int yypos1150= G->pos, yythunkpos1150= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1150; } goto l1149; - l1150:; G->pos= yypos1150; G->thunkpos= yythunkpos1150; - } if (!yymatchChar(G, '>')) goto l1146; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenDir", G->buf+G->pos)); - return 1; - l1146:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenDir", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCenter(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCenter")); if (!yy_HtmlBlockOpenCenter(G)) { goto l1151; } - l1152:; - { int yypos1153= G->pos, yythunkpos1153= G->thunkpos; - { int yypos1154= G->pos, yythunkpos1154= G->thunkpos; if (!yy_HtmlBlockCenter(G)) { goto l1155; } goto l1154; - l1155:; G->pos= yypos1154; G->thunkpos= yythunkpos1154; - { int yypos1156= G->pos, yythunkpos1156= G->thunkpos; if (!yy_HtmlBlockCloseCenter(G)) { goto l1156; } goto l1153; - l1156:; G->pos= yypos1156; G->thunkpos= yythunkpos1156; - } if (!yymatchDot(G)) goto l1153; - } - l1154:; goto l1152; - l1153:; G->pos= yypos1153; G->thunkpos= yythunkpos1153; - } if (!yy_HtmlBlockCloseCenter(G)) { goto l1151; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCenter", G->buf+G->pos)); - return 1; - l1151:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCenter", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseCenter(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseCenter")); if (!yymatchChar(G, '<')) goto l1157; if (!yy_Spnl(G)) { goto l1157; } if (!yymatchChar(G, '/')) goto l1157; - { int yypos1158= G->pos, yythunkpos1158= G->thunkpos; if (!yymatchString(G, "center")) goto l1159; goto l1158; - l1159:; G->pos= yypos1158; G->thunkpos= yythunkpos1158; if (!yymatchString(G, "CENTER")) goto l1157; - } - l1158:; if (!yy_Spnl(G)) { goto l1157; } if (!yymatchChar(G, '>')) goto l1157; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseCenter", G->buf+G->pos)); - return 1; - l1157:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseCenter", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenCenter(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenCenter")); if (!yymatchChar(G, '<')) goto l1160; if (!yy_Spnl(G)) { goto l1160; } - { int yypos1161= G->pos, yythunkpos1161= G->thunkpos; if (!yymatchString(G, "center")) goto l1162; goto l1161; - l1162:; G->pos= yypos1161; G->thunkpos= yythunkpos1161; if (!yymatchString(G, "CENTER")) goto l1160; - } - l1161:; if (!yy_Spnl(G)) { goto l1160; } - l1163:; - { int yypos1164= G->pos, yythunkpos1164= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1164; } goto l1163; - l1164:; G->pos= yypos1164; G->thunkpos= yythunkpos1164; - } if (!yymatchChar(G, '>')) goto l1160; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenCenter", G->buf+G->pos)); - return 1; - l1160:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenCenter", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockBlockquote(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockBlockquote")); if (!yy_HtmlBlockOpenBlockquote(G)) { goto l1165; } - l1166:; - { int yypos1167= G->pos, yythunkpos1167= G->thunkpos; - { int yypos1168= G->pos, yythunkpos1168= G->thunkpos; if (!yy_HtmlBlockBlockquote(G)) { goto l1169; } goto l1168; - l1169:; G->pos= yypos1168; G->thunkpos= yythunkpos1168; - { int yypos1170= G->pos, yythunkpos1170= G->thunkpos; if (!yy_HtmlBlockCloseBlockquote(G)) { goto l1170; } goto l1167; - l1170:; G->pos= yypos1170; G->thunkpos= yythunkpos1170; - } if (!yymatchDot(G)) goto l1167; - } - l1168:; goto l1166; - l1167:; G->pos= yypos1167; G->thunkpos= yythunkpos1167; - } if (!yy_HtmlBlockCloseBlockquote(G)) { goto l1165; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockBlockquote", G->buf+G->pos)); - return 1; - l1165:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockBlockquote", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseBlockquote(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseBlockquote")); if (!yymatchChar(G, '<')) goto l1171; if (!yy_Spnl(G)) { goto l1171; } if (!yymatchChar(G, '/')) goto l1171; - { int yypos1172= G->pos, yythunkpos1172= G->thunkpos; if (!yymatchString(G, "blockquote")) goto l1173; goto l1172; - l1173:; G->pos= yypos1172; G->thunkpos= yythunkpos1172; if (!yymatchString(G, "BLOCKQUOTE")) goto l1171; - } - l1172:; if (!yy_Spnl(G)) { goto l1171; } if (!yymatchChar(G, '>')) goto l1171; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseBlockquote", G->buf+G->pos)); - return 1; - l1171:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseBlockquote", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenBlockquote(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenBlockquote")); if (!yymatchChar(G, '<')) goto l1174; if (!yy_Spnl(G)) { goto l1174; } - { int yypos1175= G->pos, yythunkpos1175= G->thunkpos; if (!yymatchString(G, "blockquote")) goto l1176; goto l1175; - l1176:; G->pos= yypos1175; G->thunkpos= yythunkpos1175; if (!yymatchString(G, "BLOCKQUOTE")) goto l1174; - } - l1175:; if (!yy_Spnl(G)) { goto l1174; } - l1177:; - { int yypos1178= G->pos, yythunkpos1178= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1178; } goto l1177; - l1178:; G->pos= yypos1178; G->thunkpos= yythunkpos1178; - } if (!yymatchChar(G, '>')) goto l1174; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenBlockquote", G->buf+G->pos)); - return 1; - l1174:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenBlockquote", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockAddress(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockAddress")); if (!yy_HtmlBlockOpenAddress(G)) { goto l1179; } - l1180:; - { int yypos1181= G->pos, yythunkpos1181= G->thunkpos; - { int yypos1182= G->pos, yythunkpos1182= G->thunkpos; if (!yy_HtmlBlockAddress(G)) { goto l1183; } goto l1182; - l1183:; G->pos= yypos1182; G->thunkpos= yythunkpos1182; - { int yypos1184= G->pos, yythunkpos1184= G->thunkpos; if (!yy_HtmlBlockCloseAddress(G)) { goto l1184; } goto l1181; - l1184:; G->pos= yypos1184; G->thunkpos= yythunkpos1184; - } if (!yymatchDot(G)) goto l1181; - } - l1182:; goto l1180; - l1181:; G->pos= yypos1181; G->thunkpos= yythunkpos1181; - } if (!yy_HtmlBlockCloseAddress(G)) { goto l1179; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockAddress", G->buf+G->pos)); - return 1; - l1179:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockAddress", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseAddress(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseAddress")); if (!yymatchChar(G, '<')) goto l1185; if (!yy_Spnl(G)) { goto l1185; } if (!yymatchChar(G, '/')) goto l1185; - { int yypos1186= G->pos, yythunkpos1186= G->thunkpos; if (!yymatchString(G, "address")) goto l1187; goto l1186; - l1187:; G->pos= yypos1186; G->thunkpos= yythunkpos1186; if (!yymatchString(G, "ADDRESS")) goto l1185; - } - l1186:; if (!yy_Spnl(G)) { goto l1185; } if (!yymatchChar(G, '>')) goto l1185; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseAddress", G->buf+G->pos)); - return 1; - l1185:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseAddress", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlAttribute(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlAttribute")); - { int yypos1191= G->pos, yythunkpos1191= G->thunkpos; if (!yy_AlphanumericAscii(G)) { goto l1192; } goto l1191; - l1192:; G->pos= yypos1191; G->thunkpos= yythunkpos1191; if (!yymatchChar(G, '-')) goto l1188; - } - l1191:; - l1189:; - { int yypos1190= G->pos, yythunkpos1190= G->thunkpos; - { int yypos1193= G->pos, yythunkpos1193= G->thunkpos; if (!yy_AlphanumericAscii(G)) { goto l1194; } goto l1193; - l1194:; G->pos= yypos1193; G->thunkpos= yythunkpos1193; if (!yymatchChar(G, '-')) goto l1190; - } - l1193:; goto l1189; - l1190:; G->pos= yypos1190; G->thunkpos= yythunkpos1190; - } if (!yy_Spnl(G)) { goto l1188; } - { int yypos1195= G->pos, yythunkpos1195= G->thunkpos; if (!yymatchChar(G, '=')) goto l1195; if (!yy_Spnl(G)) { goto l1195; } - { int yypos1197= G->pos, yythunkpos1197= G->thunkpos; if (!yy_Quoted(G)) { goto l1198; } goto l1197; - l1198:; G->pos= yypos1197; G->thunkpos= yythunkpos1197; - { int yypos1201= G->pos, yythunkpos1201= G->thunkpos; if (!yymatchChar(G, '>')) goto l1201; goto l1195; - l1201:; G->pos= yypos1201; G->thunkpos= yythunkpos1201; - } if (!yy_Nonspacechar(G)) { goto l1195; } - l1199:; - { int yypos1200= G->pos, yythunkpos1200= G->thunkpos; - { int yypos1202= G->pos, yythunkpos1202= G->thunkpos; if (!yymatchChar(G, '>')) goto l1202; goto l1200; - l1202:; G->pos= yypos1202; G->thunkpos= yythunkpos1202; - } if (!yy_Nonspacechar(G)) { goto l1200; } goto l1199; - l1200:; G->pos= yypos1200; G->thunkpos= yythunkpos1200; - } - } - l1197:; goto l1196; - l1195:; G->pos= yypos1195; G->thunkpos= yythunkpos1195; - } - l1196:; if (!yy_Spnl(G)) { goto l1188; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlAttribute", G->buf+G->pos)); - return 1; - l1188:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlAttribute", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Spnl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Spnl")); if (!yy_Sp(G)) { goto l1203; } - { int yypos1204= G->pos, yythunkpos1204= G->thunkpos; if (!yy_Newline(G)) { goto l1204; } if (!yy_Sp(G)) { goto l1204; } goto l1205; - l1204:; G->pos= yypos1204; G->thunkpos= yythunkpos1204; - } - l1205:; - yyprintf((stderr, " ok %s @ %s\n", "Spnl", G->buf+G->pos)); - return 1; - l1203:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Spnl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenAddress(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenAddress")); if (!yymatchChar(G, '<')) goto l1206; if (!yy_Spnl(G)) { goto l1206; } - { int yypos1207= G->pos, yythunkpos1207= G->thunkpos; if (!yymatchString(G, "address")) goto l1208; goto l1207; - l1208:; G->pos= yypos1207; G->thunkpos= yythunkpos1207; if (!yymatchString(G, "ADDRESS")) goto l1206; - } - l1207:; if (!yy_Spnl(G)) { goto l1206; } - l1209:; - { int yypos1210= G->pos, yythunkpos1210= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1210; } goto l1209; - l1210:; G->pos= yypos1210; G->thunkpos= yythunkpos1210; - } if (!yymatchChar(G, '>')) goto l1206; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenAddress", G->buf+G->pos)); - return 1; - l1206:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenAddress", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_OptionallyIndentedLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "OptionallyIndentedLine")); - { int yypos1212= G->pos, yythunkpos1212= G->thunkpos; if (!yy_Indent(G)) { goto l1212; } goto l1213; - l1212:; G->pos= yypos1212; G->thunkpos= yythunkpos1212; - } - l1213:; if (!yy_Line(G)) { goto l1211; } - yyprintf((stderr, " ok %s @ %s\n", "OptionallyIndentedLine", G->buf+G->pos)); - return 1; - l1211:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "OptionallyIndentedLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Indent(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Indent")); - { int yypos1215= G->pos, yythunkpos1215= G->thunkpos; if (!yymatchChar(G, '\t')) goto l1216; goto l1215; - l1216:; G->pos= yypos1215; G->thunkpos= yythunkpos1215; if (!yymatchString(G, " ")) goto l1214; - } - l1215:; - yyprintf((stderr, " ok %s @ %s\n", "Indent", G->buf+G->pos)); - return 1; - l1214:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Indent", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ListBlockLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "ListBlockLine")); - { int yypos1218= G->pos, yythunkpos1218= G->thunkpos; if (!yy_BlankLine(G)) { goto l1218; } goto l1217; - l1218:; G->pos= yypos1218; G->thunkpos= yythunkpos1218; - } - { int yypos1219= G->pos, yythunkpos1219= G->thunkpos; - { int yypos1220= G->pos, yythunkpos1220= G->thunkpos; if (!yy_Indent(G)) { goto l1220; } goto l1221; - l1220:; G->pos= yypos1220; G->thunkpos= yythunkpos1220; - } - l1221:; - { int yypos1222= G->pos, yythunkpos1222= G->thunkpos; if (!yy_Bullet(G)) { goto l1223; } goto l1222; - l1223:; G->pos= yypos1222; G->thunkpos= yythunkpos1222; if (!yy_Enumerator(G)) { goto l1219; } - } - l1222:; goto l1217; - l1219:; G->pos= yypos1219; G->thunkpos= yythunkpos1219; - } - { int yypos1224= G->pos, yythunkpos1224= G->thunkpos; if (!yy_HorizontalRule(G)) { goto l1224; } goto l1217; - l1224:; G->pos= yypos1224; G->thunkpos= yythunkpos1224; - } if (!yy_OptionallyIndentedLine(G)) { goto l1217; } - yyprintf((stderr, " ok %s @ %s\n", "ListBlockLine", G->buf+G->pos)); - return 1; - l1217:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ListBlockLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ListContinuationBlock(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "ListContinuationBlock")); if (!yy_StartList(G)) { goto l1225; } yyDo(G, yySet, -1, 0); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1225; - l1226:; - { int yypos1227= G->pos, yythunkpos1227= G->thunkpos; if (!yy_BlankLine(G)) { goto l1227; } goto l1226; - l1227:; G->pos= yypos1227; G->thunkpos= yythunkpos1227; - } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1225; yyDo(G, yy_1_ListContinuationBlock, G->begin, G->end); if (!yy_Indent(G)) { goto l1225; } if (!yy_ListBlock(G)) { goto l1225; } yyDo(G, yy_2_ListContinuationBlock, G->begin, G->end); - l1228:; - { int yypos1229= G->pos, yythunkpos1229= G->thunkpos; if (!yy_Indent(G)) { goto l1229; } if (!yy_ListBlock(G)) { goto l1229; } yyDo(G, yy_2_ListContinuationBlock, G->begin, G->end); goto l1228; - l1229:; G->pos= yypos1229; G->thunkpos= yythunkpos1229; - } yyDo(G, yy_3_ListContinuationBlock, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ListContinuationBlock", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1225:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ListContinuationBlock", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ListBlock(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "ListBlock")); if (!yy_StartList(G)) { goto l1230; } yyDo(G, yySet, -1, 0); - { int yypos1231= G->pos, yythunkpos1231= G->thunkpos; if (!yy_BlankLine(G)) { goto l1231; } goto l1230; - l1231:; G->pos= yypos1231; G->thunkpos= yythunkpos1231; - } if (!yy_Line(G)) { goto l1230; } yyDo(G, yy_1_ListBlock, G->begin, G->end); - l1232:; - { int yypos1233= G->pos, yythunkpos1233= G->thunkpos; if (!yy_ListBlockLine(G)) { goto l1233; } yyDo(G, yy_2_ListBlock, G->begin, G->end); goto l1232; - l1233:; G->pos= yypos1233; G->thunkpos= yythunkpos1233; - } yyDo(G, yy_3_ListBlock, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ListBlock", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1230:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ListBlock", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ListItem(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "ListItem")); - { int yypos1235= G->pos, yythunkpos1235= G->thunkpos; if (!yy_Bullet(G)) { goto l1236; } goto l1235; - l1236:; G->pos= yypos1235; G->thunkpos= yythunkpos1235; if (!yy_Enumerator(G)) { goto l1234; } - } - l1235:; if (!yy_StartList(G)) { goto l1234; } yyDo(G, yySet, -1, 0); if (!yy_ListBlock(G)) { goto l1234; } yyDo(G, yy_1_ListItem, G->begin, G->end); - l1237:; - { int yypos1238= G->pos, yythunkpos1238= G->thunkpos; if (!yy_ListContinuationBlock(G)) { goto l1238; } yyDo(G, yy_2_ListItem, G->begin, G->end); goto l1237; - l1238:; G->pos= yypos1238; G->thunkpos= yythunkpos1238; - } yyDo(G, yy_3_ListItem, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ListItem", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1234:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ListItem", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Enumerator(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Enumerator")); if (!yy_NonindentSpace(G)) { goto l1239; } yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1239; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l1239; - l1240:; - { int yypos1241= G->pos, yythunkpos1241= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l1241; goto l1240; - l1241:; G->pos= yypos1241; G->thunkpos= yythunkpos1241; - } if (!yymatchChar(G, '.')) goto l1239; yyText(G, G->begin, G->end); if (!(YY_END)) goto l1239; if (!yy_Spacechar(G)) { goto l1239; } - l1242:; - { int yypos1243= G->pos, yythunkpos1243= G->thunkpos; if (!yy_Spacechar(G)) { goto l1243; } goto l1242; - l1243:; G->pos= yypos1243; G->thunkpos= yythunkpos1243; - } yyDo(G, yy_1_Enumerator, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Enumerator", G->buf+G->pos)); - return 1; - l1239:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Enumerator", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ListItemTight(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "ListItemTight")); - { int yypos1245= G->pos, yythunkpos1245= G->thunkpos; if (!yy_Bullet(G)) { goto l1246; } goto l1245; - l1246:; G->pos= yypos1245; G->thunkpos= yythunkpos1245; if (!yy_Enumerator(G)) { goto l1244; } - } - l1245:; if (!yy_StartList(G)) { goto l1244; } yyDo(G, yySet, -1, 0); if (!yy_ListBlock(G)) { goto l1244; } yyDo(G, yy_1_ListItemTight, G->begin, G->end); - l1247:; - { int yypos1248= G->pos, yythunkpos1248= G->thunkpos; - { int yypos1249= G->pos, yythunkpos1249= G->thunkpos; if (!yy_BlankLine(G)) { goto l1249; } goto l1248; - l1249:; G->pos= yypos1249; G->thunkpos= yythunkpos1249; - } if (!yy_ListContinuationBlock(G)) { goto l1248; } yyDo(G, yy_2_ListItemTight, G->begin, G->end); goto l1247; - l1248:; G->pos= yypos1248; G->thunkpos= yythunkpos1248; - } - { int yypos1250= G->pos, yythunkpos1250= G->thunkpos; if (!yy_ListContinuationBlock(G)) { goto l1250; } goto l1244; - l1250:; G->pos= yypos1250; G->thunkpos= yythunkpos1250; - } yyDo(G, yy_3_ListItemTight, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ListItemTight", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1244:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ListItemTight", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ListLoose(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 2, 0); - yyprintf((stderr, "%s\n", "ListLoose")); if (!yy_StartList(G)) { goto l1251; } yyDo(G, yySet, -2, 0); if (!yy_ListItem(G)) { goto l1251; } yyDo(G, yySet, -1, 0); - l1254:; - { int yypos1255= G->pos, yythunkpos1255= G->thunkpos; if (!yy_BlankLine(G)) { goto l1255; } goto l1254; - l1255:; G->pos= yypos1255; G->thunkpos= yythunkpos1255; - } yyDo(G, yy_1_ListLoose, G->begin, G->end); - l1252:; - { int yypos1253= G->pos, yythunkpos1253= G->thunkpos; if (!yy_ListItem(G)) { goto l1253; } yyDo(G, yySet, -1, 0); - l1256:; - { int yypos1257= G->pos, yythunkpos1257= G->thunkpos; if (!yy_BlankLine(G)) { goto l1257; } goto l1256; - l1257:; G->pos= yypos1257; G->thunkpos= yythunkpos1257; - } yyDo(G, yy_1_ListLoose, G->begin, G->end); goto l1252; - l1253:; G->pos= yypos1253; G->thunkpos= yythunkpos1253; - } yyDo(G, yy_2_ListLoose, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ListLoose", G->buf+G->pos)); yyDo(G, yyPop, 2, 0); - return 1; - l1251:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ListLoose", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ListTight(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "ListTight")); if (!yy_StartList(G)) { goto l1258; } yyDo(G, yySet, -1, 0); if (!yy_ListItemTight(G)) { goto l1258; } yyDo(G, yy_1_ListTight, G->begin, G->end); - l1259:; - { int yypos1260= G->pos, yythunkpos1260= G->thunkpos; if (!yy_ListItemTight(G)) { goto l1260; } yyDo(G, yy_1_ListTight, G->begin, G->end); goto l1259; - l1260:; G->pos= yypos1260; G->thunkpos= yythunkpos1260; - } - l1261:; - { int yypos1262= G->pos, yythunkpos1262= G->thunkpos; if (!yy_BlankLine(G)) { goto l1262; } goto l1261; - l1262:; G->pos= yypos1262; G->thunkpos= yythunkpos1262; - } - { int yypos1263= G->pos, yythunkpos1263= G->thunkpos; - { int yypos1264= G->pos, yythunkpos1264= G->thunkpos; if (!yy_Bullet(G)) { goto l1265; } goto l1264; - l1265:; G->pos= yypos1264; G->thunkpos= yythunkpos1264; if (!yy_Enumerator(G)) { goto l1263; } - } - l1264:; goto l1258; - l1263:; G->pos= yypos1263; G->thunkpos= yythunkpos1263; - } yyDo(G, yy_2_ListTight, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ListTight", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1258:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ListTight", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Spacechar(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Spacechar")); - { int yypos1267= G->pos, yythunkpos1267= G->thunkpos; if (!yymatchChar(G, ' ')) goto l1268; goto l1267; - l1268:; G->pos= yypos1267; G->thunkpos= yythunkpos1267; if (!yymatchChar(G, '\t')) goto l1266; - } - l1267:; - yyprintf((stderr, " ok %s @ %s\n", "Spacechar", G->buf+G->pos)); - return 1; - l1266:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Spacechar", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Bullet(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Bullet")); - { int yypos1270= G->pos, yythunkpos1270= G->thunkpos; if (!yy_HorizontalRule(G)) { goto l1270; } goto l1269; - l1270:; G->pos= yypos1270; G->thunkpos= yythunkpos1270; - } if (!yy_NonindentSpace(G)) { goto l1269; } yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1269; - { int yypos1271= G->pos, yythunkpos1271= G->thunkpos; if (!yymatchChar(G, '+')) goto l1272; goto l1271; - l1272:; G->pos= yypos1271; G->thunkpos= yythunkpos1271; if (!yymatchChar(G, '*')) goto l1273; goto l1271; - l1273:; G->pos= yypos1271; G->thunkpos= yythunkpos1271; if (!yymatchChar(G, '-')) goto l1269; - } - l1271:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l1269; if (!yy_Spacechar(G)) { goto l1269; } - l1274:; - { int yypos1275= G->pos, yythunkpos1275= G->thunkpos; if (!yy_Spacechar(G)) { goto l1275; } goto l1274; - l1275:; G->pos= yypos1275; G->thunkpos= yythunkpos1275; - } yyDo(G, yy_1_Bullet, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Bullet", G->buf+G->pos)); - return 1; - l1269:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Bullet", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_VerbatimChunk(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "VerbatimChunk")); - l1277:; - { int yypos1278= G->pos, yythunkpos1278= G->thunkpos; if (!yy_BlankLine(G)) { goto l1278; } goto l1277; - l1278:; G->pos= yypos1278; G->thunkpos= yythunkpos1278; - } if (!yy_NonblankIndentedLine(G)) { goto l1276; } - l1279:; - { int yypos1280= G->pos, yythunkpos1280= G->thunkpos; if (!yy_NonblankIndentedLine(G)) { goto l1280; } goto l1279; - l1280:; G->pos= yypos1280; G->thunkpos= yythunkpos1280; - } - yyprintf((stderr, " ok %s @ %s\n", "VerbatimChunk", G->buf+G->pos)); - return 1; - l1276:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "VerbatimChunk", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_IndentedLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "IndentedLine")); if (!yy_Indent(G)) { goto l1281; } if (!yy_Line(G)) { goto l1281; } - yyprintf((stderr, " ok %s @ %s\n", "IndentedLine", G->buf+G->pos)); - return 1; - l1281:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "IndentedLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_NonblankIndentedLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "NonblankIndentedLine")); - { int yypos1283= G->pos, yythunkpos1283= G->thunkpos; if (!yy_BlankLine(G)) { goto l1283; } goto l1282; - l1283:; G->pos= yypos1283; G->thunkpos= yythunkpos1283; - } if (!yy_IndentedLine(G)) { goto l1282; } - yyprintf((stderr, " ok %s @ %s\n", "NonblankIndentedLine", G->buf+G->pos)); - return 1; - l1282:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "NonblankIndentedLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Line(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Line")); if (!yy_RawLine(G)) { goto l1284; } yyDo(G, yy_1_Line, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Line", G->buf+G->pos)); - return 1; - l1284:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Line", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_StartList(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "StartList")); - { int yypos1286= G->pos, yythunkpos1286= G->thunkpos; if (!yymatchDot(G)) goto l1285; G->pos= yypos1286; G->thunkpos= yythunkpos1286; - } yyDo(G, yy_1_StartList, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "StartList", G->buf+G->pos)); - return 1; - l1285:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "StartList", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_BlockQuoteRaw(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "BlockQuoteRaw")); if (!yy_StartList(G)) { goto l1287; } yyDo(G, yySet, -1, 0); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1287; if (!yymatchChar(G, '>')) goto l1287; - { int yypos1290= G->pos, yythunkpos1290= G->thunkpos; if (!yymatchChar(G, ' ')) goto l1290; goto l1291; - l1290:; G->pos= yypos1290; G->thunkpos= yythunkpos1290; - } - l1291:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l1287; yyDo(G, yy_1_BlockQuoteRaw, G->begin, G->end); if (!yy_Line(G)) { goto l1287; } yyDo(G, yy_2_BlockQuoteRaw, G->begin, G->end); - l1292:; - { int yypos1293= G->pos, yythunkpos1293= G->thunkpos; - { int yypos1294= G->pos, yythunkpos1294= G->thunkpos; if (!yymatchChar(G, '>')) goto l1294; goto l1293; - l1294:; G->pos= yypos1294; G->thunkpos= yythunkpos1294; - } - { int yypos1295= G->pos, yythunkpos1295= G->thunkpos; if (!yy_BlankLine(G)) { goto l1295; } goto l1293; - l1295:; G->pos= yypos1295; G->thunkpos= yythunkpos1295; - } if (!yy_Line(G)) { goto l1293; } yyDo(G, yy_3_BlockQuoteRaw, G->begin, G->end); goto l1292; - l1293:; G->pos= yypos1293; G->thunkpos= yythunkpos1293; - } - l1296:; - { int yypos1297= G->pos, yythunkpos1297= G->thunkpos; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1297; if (!yy_BlankLine(G)) { goto l1297; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1297; yyDo(G, yy_4_BlockQuoteRaw, G->begin, G->end); goto l1296; - l1297:; G->pos= yypos1297; G->thunkpos= yythunkpos1297; - } - l1288:; - { int yypos1289= G->pos, yythunkpos1289= G->thunkpos; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1289; if (!yymatchChar(G, '>')) goto l1289; - { int yypos1298= G->pos, yythunkpos1298= G->thunkpos; if (!yymatchChar(G, ' ')) goto l1298; goto l1299; - l1298:; G->pos= yypos1298; G->thunkpos= yythunkpos1298; - } - l1299:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l1289; yyDo(G, yy_1_BlockQuoteRaw, G->begin, G->end); if (!yy_Line(G)) { goto l1289; } yyDo(G, yy_2_BlockQuoteRaw, G->begin, G->end); - l1300:; - { int yypos1301= G->pos, yythunkpos1301= G->thunkpos; - { int yypos1302= G->pos, yythunkpos1302= G->thunkpos; if (!yymatchChar(G, '>')) goto l1302; goto l1301; - l1302:; G->pos= yypos1302; G->thunkpos= yythunkpos1302; - } - { int yypos1303= G->pos, yythunkpos1303= G->thunkpos; if (!yy_BlankLine(G)) { goto l1303; } goto l1301; - l1303:; G->pos= yypos1303; G->thunkpos= yythunkpos1303; - } if (!yy_Line(G)) { goto l1301; } yyDo(G, yy_3_BlockQuoteRaw, G->begin, G->end); goto l1300; - l1301:; G->pos= yypos1301; G->thunkpos= yythunkpos1301; - } - l1304:; - { int yypos1305= G->pos, yythunkpos1305= G->thunkpos; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1305; if (!yy_BlankLine(G)) { goto l1305; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1305; yyDo(G, yy_4_BlockQuoteRaw, G->begin, G->end); goto l1304; - l1305:; G->pos= yypos1305; G->thunkpos= yythunkpos1305; - } goto l1288; - l1289:; G->pos= yypos1289; G->thunkpos= yythunkpos1289; - } yyDo(G, yy_5_BlockQuoteRaw, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "BlockQuoteRaw", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1287:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "BlockQuoteRaw", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Endline(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Endline")); - { int yypos1307= G->pos, yythunkpos1307= G->thunkpos; if (!yy_LineBreak(G)) { goto l1308; } goto l1307; - l1308:; G->pos= yypos1307; G->thunkpos= yythunkpos1307; if (!yy_TerminalEndline(G)) { goto l1309; } goto l1307; - l1309:; G->pos= yypos1307; G->thunkpos= yythunkpos1307; if (!yy_NormalEndline(G)) { goto l1306; } - } - l1307:; - yyprintf((stderr, " ok %s @ %s\n", "Endline", G->buf+G->pos)); - return 1; - l1306:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Endline", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_RawLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "RawLine")); - { int yypos1311= G->pos, yythunkpos1311= G->thunkpos; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1312; - l1313:; - { int yypos1314= G->pos, yythunkpos1314= G->thunkpos; - { int yypos1315= G->pos, yythunkpos1315= G->thunkpos; if (!yymatchChar(G, '\r')) goto l1315; goto l1314; - l1315:; G->pos= yypos1315; G->thunkpos= yythunkpos1315; - } - { int yypos1316= G->pos, yythunkpos1316= G->thunkpos; if (!yymatchChar(G, '\n')) goto l1316; goto l1314; - l1316:; G->pos= yypos1316; G->thunkpos= yythunkpos1316; - } if (!yymatchDot(G)) goto l1314; goto l1313; - l1314:; G->pos= yypos1314; G->thunkpos= yythunkpos1314; - } if (!yy_Newline(G)) { goto l1312; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1312; goto l1311; - l1312:; G->pos= yypos1311; G->thunkpos= yythunkpos1311; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1310; if (!yymatchDot(G)) goto l1310; - l1317:; - { int yypos1318= G->pos, yythunkpos1318= G->thunkpos; if (!yymatchDot(G)) goto l1318; goto l1317; - l1318:; G->pos= yypos1318; G->thunkpos= yythunkpos1318; - } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1310; if (!yy_Eof(G)) { goto l1310; } - } - l1311:; yyDo(G, yy_1_RawLine, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "RawLine", G->buf+G->pos)); - return 1; - l1310:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RawLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_SetextBottom2(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "SetextBottom2")); if (!yymatchChar(G, '-')) goto l1319; - l1320:; - { int yypos1321= G->pos, yythunkpos1321= G->thunkpos; if (!yymatchChar(G, '-')) goto l1321; goto l1320; - l1321:; G->pos= yypos1321; G->thunkpos= yythunkpos1321; - } if (!yy_Newline(G)) { goto l1319; } - yyprintf((stderr, " ok %s @ %s\n", "SetextBottom2", G->buf+G->pos)); - return 1; - l1319:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "SetextBottom2", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_SetextBottom1(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "SetextBottom1")); if (!yymatchChar(G, '=')) goto l1322; - l1323:; - { int yypos1324= G->pos, yythunkpos1324= G->thunkpos; if (!yymatchChar(G, '=')) goto l1324; goto l1323; - l1324:; G->pos= yypos1324; G->thunkpos= yythunkpos1324; - } if (!yy_Newline(G)) { goto l1322; } - yyprintf((stderr, " ok %s @ %s\n", "SetextBottom1", G->buf+G->pos)); - return 1; - l1322:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "SetextBottom1", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_SetextHeading2(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "SetextHeading2")); - { int yypos1326= G->pos, yythunkpos1326= G->thunkpos; if (!yy_RawLine(G)) { goto l1325; } if (!yy_SetextBottom2(G)) { goto l1325; } G->pos= yypos1326; G->thunkpos= yythunkpos1326; - } if (!yy_LocMarker(G)) { goto l1325; } yyDo(G, yySet, -1, 0); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1325; - { int yypos1329= G->pos, yythunkpos1329= G->thunkpos; if (!yy_Endline(G)) { goto l1329; } goto l1325; - l1329:; G->pos= yypos1329; G->thunkpos= yythunkpos1329; - } if (!yy_Inline(G)) { goto l1325; } - l1327:; - { int yypos1328= G->pos, yythunkpos1328= G->thunkpos; - { int yypos1330= G->pos, yythunkpos1330= G->thunkpos; if (!yy_Endline(G)) { goto l1330; } goto l1328; - l1330:; G->pos= yypos1330; G->thunkpos= yythunkpos1330; - } if (!yy_Inline(G)) { goto l1328; } goto l1327; - l1328:; G->pos= yypos1328; G->thunkpos= yythunkpos1328; - } if (!yy_Sp(G)) { goto l1325; } if (!yy_Newline(G)) { goto l1325; } if (!yy_SetextBottom2(G)) { goto l1325; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1325; yyDo(G, yy_1_SetextHeading2, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "SetextHeading2", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1325:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "SetextHeading2", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_SetextHeading1(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "SetextHeading1")); - { int yypos1332= G->pos, yythunkpos1332= G->thunkpos; if (!yy_RawLine(G)) { goto l1331; } if (!yy_SetextBottom1(G)) { goto l1331; } G->pos= yypos1332; G->thunkpos= yythunkpos1332; - } if (!yy_LocMarker(G)) { goto l1331; } yyDo(G, yySet, -1, 0); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1331; - { int yypos1335= G->pos, yythunkpos1335= G->thunkpos; if (!yy_Endline(G)) { goto l1335; } goto l1331; - l1335:; G->pos= yypos1335; G->thunkpos= yythunkpos1335; - } if (!yy_Inline(G)) { goto l1331; } - l1333:; - { int yypos1334= G->pos, yythunkpos1334= G->thunkpos; - { int yypos1336= G->pos, yythunkpos1336= G->thunkpos; if (!yy_Endline(G)) { goto l1336; } goto l1334; - l1336:; G->pos= yypos1336; G->thunkpos= yythunkpos1336; - } if (!yy_Inline(G)) { goto l1334; } goto l1333; - l1334:; G->pos= yypos1334; G->thunkpos= yythunkpos1334; - } if (!yy_Sp(G)) { goto l1331; } if (!yy_Newline(G)) { goto l1331; } if (!yy_SetextBottom1(G)) { goto l1331; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1331; yyDo(G, yy_1_SetextHeading1, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "SetextHeading1", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1331:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "SetextHeading1", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_SetextHeading(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "SetextHeading")); - { int yypos1338= G->pos, yythunkpos1338= G->thunkpos; if (!yy_SetextHeading1(G)) { goto l1339; } goto l1338; - l1339:; G->pos= yypos1338; G->thunkpos= yythunkpos1338; if (!yy_SetextHeading2(G)) { goto l1337; } - } - l1338:; - yyprintf((stderr, " ok %s @ %s\n", "SetextHeading", G->buf+G->pos)); - return 1; - l1337:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "SetextHeading", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_AtxHeading(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "AtxHeading")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1340; if (!yy_AtxStart(G)) { goto l1340; } yyDo(G, yySet, -1, 0); if (!yy_Sp(G)) { goto l1340; } if (!yy_AtxInline(G)) { goto l1340; } - l1341:; - { int yypos1342= G->pos, yythunkpos1342= G->thunkpos; if (!yy_AtxInline(G)) { goto l1342; } goto l1341; - l1342:; G->pos= yypos1342; G->thunkpos= yythunkpos1342; - } - { int yypos1343= G->pos, yythunkpos1343= G->thunkpos; if (!yy_Sp(G)) { goto l1343; } - l1345:; - { int yypos1346= G->pos, yythunkpos1346= G->thunkpos; if (!yymatchChar(G, '#')) goto l1346; goto l1345; - l1346:; G->pos= yypos1346; G->thunkpos= yythunkpos1346; - } if (!yy_Sp(G)) { goto l1343; } goto l1344; - l1343:; G->pos= yypos1343; G->thunkpos= yythunkpos1343; - } - l1344:; if (!yy_Newline(G)) { goto l1340; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1340; yyDo(G, yy_1_AtxHeading, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "AtxHeading", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1340:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "AtxHeading", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_AtxStart(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "AtxStart")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1347; - { int yypos1348= G->pos, yythunkpos1348= G->thunkpos; if (!yymatchString(G, "######")) goto l1349; goto l1348; - l1349:; G->pos= yypos1348; G->thunkpos= yythunkpos1348; if (!yymatchString(G, "#####")) goto l1350; goto l1348; - l1350:; G->pos= yypos1348; G->thunkpos= yythunkpos1348; if (!yymatchString(G, "####")) goto l1351; goto l1348; - l1351:; G->pos= yypos1348; G->thunkpos= yythunkpos1348; if (!yymatchString(G, "###")) goto l1352; goto l1348; - l1352:; G->pos= yypos1348; G->thunkpos= yythunkpos1348; if (!yymatchString(G, "##")) goto l1353; goto l1348; - l1353:; G->pos= yypos1348; G->thunkpos= yythunkpos1348; if (!yymatchChar(G, '#')) goto l1347; - } - l1348:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l1347; yyDo(G, yy_1_AtxStart, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "AtxStart", G->buf+G->pos)); - return 1; - l1347:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "AtxStart", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Inline(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Inline")); - { int yypos1355= G->pos, yythunkpos1355= G->thunkpos; if (!yy_Str(G)) { goto l1356; } goto l1355; - l1356:; G->pos= yypos1355; G->thunkpos= yythunkpos1355; if (!yy_Endline(G)) { goto l1357; } goto l1355; - l1357:; G->pos= yypos1355; G->thunkpos= yythunkpos1355; if (!yy_UlOrStarLine(G)) { goto l1358; } goto l1355; - l1358:; G->pos= yypos1355; G->thunkpos= yythunkpos1355; if (!yy_Space(G)) { goto l1359; } goto l1355; - l1359:; G->pos= yypos1355; G->thunkpos= yythunkpos1355; if (!yy_Strong(G)) { goto l1360; } goto l1355; - l1360:; G->pos= yypos1355; G->thunkpos= yythunkpos1355; if (!yy_Emph(G)) { goto l1361; } goto l1355; - l1361:; G->pos= yypos1355; G->thunkpos= yythunkpos1355; if (!yy_Strike(G)) { goto l1362; } goto l1355; - l1362:; G->pos= yypos1355; G->thunkpos= yythunkpos1355; if (!yy_Image(G)) { goto l1363; } goto l1355; - l1363:; G->pos= yypos1355; G->thunkpos= yythunkpos1355; if (!yy_Link(G)) { goto l1364; } goto l1355; - l1364:; G->pos= yypos1355; G->thunkpos= yythunkpos1355; if (!yy_NoteReference(G)) { goto l1365; } goto l1355; - l1365:; G->pos= yypos1355; G->thunkpos= yythunkpos1355; if (!yy_InlineNote(G)) { goto l1366; } goto l1355; - l1366:; G->pos= yypos1355; G->thunkpos= yythunkpos1355; if (!yy_Code(G)) { goto l1367; } goto l1355; - l1367:; G->pos= yypos1355; G->thunkpos= yythunkpos1355; if (!yy_RawHtml(G)) { goto l1368; } goto l1355; - l1368:; G->pos= yypos1355; G->thunkpos= yythunkpos1355; if (!yy_Entity(G)) { goto l1369; } goto l1355; - l1369:; G->pos= yypos1355; G->thunkpos= yythunkpos1355; if (!yy_EscapedChar(G)) { goto l1370; } goto l1355; - l1370:; G->pos= yypos1355; G->thunkpos= yythunkpos1355; if (!yy_Symbol(G)) { goto l1354; } - } - l1355:; - yyprintf((stderr, " ok %s @ %s\n", "Inline", G->buf+G->pos)); - return 1; - l1354:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Inline", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Sp(GREG *G) -{ - yyprintf((stderr, "%s\n", "Sp")); - l1372:; - { int yypos1373= G->pos, yythunkpos1373= G->thunkpos; if (!yy_Spacechar(G)) { goto l1373; } goto l1372; - l1373:; G->pos= yypos1373; G->thunkpos= yythunkpos1373; - } - yyprintf((stderr, " ok %s @ %s\n", "Sp", G->buf+G->pos)); - return 1; -} -YY_RULE(int) yy_Newline(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Newline")); - { int yypos1375= G->pos, yythunkpos1375= G->thunkpos; if (!yymatchChar(G, '\n')) goto l1376; goto l1375; - l1376:; G->pos= yypos1375; G->thunkpos= yythunkpos1375; if (!yymatchChar(G, '\r')) goto l1374; - { int yypos1377= G->pos, yythunkpos1377= G->thunkpos; if (!yymatchChar(G, '\n')) goto l1377; goto l1378; - l1377:; G->pos= yypos1377; G->thunkpos= yythunkpos1377; - } - l1378:; - } - l1375:; - yyprintf((stderr, " ok %s @ %s\n", "Newline", G->buf+G->pos)); - return 1; - l1374:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Newline", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_AtxInline(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "AtxInline")); - { int yypos1380= G->pos, yythunkpos1380= G->thunkpos; if (!yy_Newline(G)) { goto l1380; } goto l1379; - l1380:; G->pos= yypos1380; G->thunkpos= yythunkpos1380; - } - { int yypos1381= G->pos, yythunkpos1381= G->thunkpos; if (!yy_Sp(G)) { goto l1381; } - l1382:; - { int yypos1383= G->pos, yythunkpos1383= G->thunkpos; if (!yymatchChar(G, '#')) goto l1383; goto l1382; - l1383:; G->pos= yypos1383; G->thunkpos= yythunkpos1383; - } if (!yy_Sp(G)) { goto l1381; } if (!yy_Newline(G)) { goto l1381; } goto l1379; - l1381:; G->pos= yypos1381; G->thunkpos= yythunkpos1381; - } if (!yy_Inline(G)) { goto l1379; } - yyprintf((stderr, " ok %s @ %s\n", "AtxInline", G->buf+G->pos)); - return 1; - l1379:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "AtxInline", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Inlines(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Inlines")); - { int yypos1387= G->pos, yythunkpos1387= G->thunkpos; - { int yypos1389= G->pos, yythunkpos1389= G->thunkpos; if (!yy_Endline(G)) { goto l1389; } goto l1388; - l1389:; G->pos= yypos1389; G->thunkpos= yythunkpos1389; - } if (!yy_Inline(G)) { goto l1388; } goto l1387; - l1388:; G->pos= yypos1387; G->thunkpos= yythunkpos1387; if (!yy_Endline(G)) { goto l1384; } - { int yypos1390= G->pos, yythunkpos1390= G->thunkpos; if (!yy_Inline(G)) { goto l1384; } G->pos= yypos1390; G->thunkpos= yythunkpos1390; - } - } - l1387:; - l1385:; - { int yypos1386= G->pos, yythunkpos1386= G->thunkpos; - { int yypos1391= G->pos, yythunkpos1391= G->thunkpos; - { int yypos1393= G->pos, yythunkpos1393= G->thunkpos; if (!yy_Endline(G)) { goto l1393; } goto l1392; - l1393:; G->pos= yypos1393; G->thunkpos= yythunkpos1393; - } if (!yy_Inline(G)) { goto l1392; } goto l1391; - l1392:; G->pos= yypos1391; G->thunkpos= yythunkpos1391; if (!yy_Endline(G)) { goto l1386; } - { int yypos1394= G->pos, yythunkpos1394= G->thunkpos; if (!yy_Inline(G)) { goto l1386; } G->pos= yypos1394; G->thunkpos= yythunkpos1394; - } - } - l1391:; goto l1385; - l1386:; G->pos= yypos1386; G->thunkpos= yythunkpos1386; - } - { int yypos1395= G->pos, yythunkpos1395= G->thunkpos; if (!yy_Endline(G)) { goto l1395; } goto l1396; - l1395:; G->pos= yypos1395; G->thunkpos= yythunkpos1395; - } - l1396:; - yyprintf((stderr, " ok %s @ %s\n", "Inlines", G->buf+G->pos)); - return 1; - l1384:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Inlines", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_NonindentSpace(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "NonindentSpace")); - { int yypos1398= G->pos, yythunkpos1398= G->thunkpos; if (!yymatchString(G, " ")) goto l1399; goto l1398; - l1399:; G->pos= yypos1398; G->thunkpos= yythunkpos1398; if (!yymatchString(G, " ")) goto l1400; goto l1398; - l1400:; G->pos= yypos1398; G->thunkpos= yythunkpos1398; if (!yymatchChar(G, ' ')) goto l1401; goto l1398; - l1401:; G->pos= yypos1398; G->thunkpos= yythunkpos1398; if (!yymatchString(G, "")) goto l1397; - } - l1398:; - yyprintf((stderr, " ok %s @ %s\n", "NonindentSpace", G->buf+G->pos)); - return 1; - l1397:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "NonindentSpace", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Plain(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Plain")); if (!yy_Inlines(G)) { goto l1402; } - yyprintf((stderr, " ok %s @ %s\n", "Plain", G->buf+G->pos)); - return 1; - l1402:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Plain", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Para(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Para")); if (!yy_NonindentSpace(G)) { goto l1403; } if (!yy_Inlines(G)) { goto l1403; } if (!yy_BlankLine(G)) { goto l1403; } - l1404:; - { int yypos1405= G->pos, yythunkpos1405= G->thunkpos; if (!yy_BlankLine(G)) { goto l1405; } goto l1404; - l1405:; G->pos= yypos1405; G->thunkpos= yythunkpos1405; - } - yyprintf((stderr, " ok %s @ %s\n", "Para", G->buf+G->pos)); - return 1; - l1403:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Para", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_StyleBlock(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "StyleBlock")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1406; if (!yy_LocMarker(G)) { goto l1406; } yyDo(G, yySet, -1, 0); if (!yy_InStyleTags(G)) { goto l1406; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1406; - l1407:; - { int yypos1408= G->pos, yythunkpos1408= G->thunkpos; if (!yy_BlankLine(G)) { goto l1408; } goto l1407; - l1408:; G->pos= yypos1408; G->thunkpos= yythunkpos1408; - } yyDo(G, yy_1_StyleBlock, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "StyleBlock", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1406:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "StyleBlock", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlock(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "HtmlBlock")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1409; if (!yy_LocMarker(G)) { goto l1409; } yyDo(G, yySet, -1, 0); - { int yypos1410= G->pos, yythunkpos1410= G->thunkpos; if (!yy_HtmlBlockInTags(G)) { goto l1411; } goto l1410; - l1411:; G->pos= yypos1410; G->thunkpos= yythunkpos1410; if (!yy_HtmlComment(G)) { goto l1412; } goto l1410; - l1412:; G->pos= yypos1410; G->thunkpos= yythunkpos1410; if (!yy_HtmlBlockSelfClosing(G)) { goto l1409; } - } - l1410:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l1409; if (!yy_BlankLine(G)) { goto l1409; } - l1413:; - { int yypos1414= G->pos, yythunkpos1414= G->thunkpos; if (!yy_BlankLine(G)) { goto l1414; } goto l1413; - l1414:; G->pos= yypos1414; G->thunkpos= yythunkpos1414; - } yyDo(G, yy_1_HtmlBlock, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlock", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1409:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlock", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_BulletList(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "BulletList")); - { int yypos1416= G->pos, yythunkpos1416= G->thunkpos; if (!yy_Bullet(G)) { goto l1415; } G->pos= yypos1416; G->thunkpos= yythunkpos1416; - } - { int yypos1417= G->pos, yythunkpos1417= G->thunkpos; if (!yy_ListTight(G)) { goto l1418; } goto l1417; - l1418:; G->pos= yypos1417; G->thunkpos= yythunkpos1417; if (!yy_ListLoose(G)) { goto l1415; } - } - l1417:; - yyprintf((stderr, " ok %s @ %s\n", "BulletList", G->buf+G->pos)); - return 1; - l1415:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "BulletList", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_OrderedList(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "OrderedList")); - { int yypos1420= G->pos, yythunkpos1420= G->thunkpos; if (!yy_Enumerator(G)) { goto l1419; } G->pos= yypos1420; G->thunkpos= yythunkpos1420; - } - { int yypos1421= G->pos, yythunkpos1421= G->thunkpos; if (!yy_ListTight(G)) { goto l1422; } goto l1421; - l1422:; G->pos= yypos1421; G->thunkpos= yythunkpos1421; if (!yy_ListLoose(G)) { goto l1419; } - } - l1421:; - yyprintf((stderr, " ok %s @ %s\n", "OrderedList", G->buf+G->pos)); - return 1; - l1419:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "OrderedList", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Heading(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Heading")); - { int yypos1424= G->pos, yythunkpos1424= G->thunkpos; if (!yy_SetextHeading(G)) { goto l1425; } goto l1424; - l1425:; G->pos= yypos1424; G->thunkpos= yythunkpos1424; if (!yy_AtxHeading(G)) { goto l1423; } - } - l1424:; - yyprintf((stderr, " ok %s @ %s\n", "Heading", G->buf+G->pos)); - return 1; - l1423:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Heading", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HorizontalRule(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HorizontalRule")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1426; if (!yy_NonindentSpace(G)) { goto l1426; } - { int yypos1427= G->pos, yythunkpos1427= G->thunkpos; if (!yymatchChar(G, '*')) goto l1428; if (!yy_Sp(G)) { goto l1428; } if (!yymatchChar(G, '*')) goto l1428; if (!yy_Sp(G)) { goto l1428; } if (!yymatchChar(G, '*')) goto l1428; - l1429:; - { int yypos1430= G->pos, yythunkpos1430= G->thunkpos; if (!yy_Sp(G)) { goto l1430; } if (!yymatchChar(G, '*')) goto l1430; goto l1429; - l1430:; G->pos= yypos1430; G->thunkpos= yythunkpos1430; - } goto l1427; - l1428:; G->pos= yypos1427; G->thunkpos= yythunkpos1427; if (!yymatchChar(G, '-')) goto l1431; if (!yy_Sp(G)) { goto l1431; } if (!yymatchChar(G, '-')) goto l1431; if (!yy_Sp(G)) { goto l1431; } if (!yymatchChar(G, '-')) goto l1431; - l1432:; - { int yypos1433= G->pos, yythunkpos1433= G->thunkpos; if (!yy_Sp(G)) { goto l1433; } if (!yymatchChar(G, '-')) goto l1433; goto l1432; - l1433:; G->pos= yypos1433; G->thunkpos= yythunkpos1433; - } goto l1427; - l1431:; G->pos= yypos1427; G->thunkpos= yythunkpos1427; if (!yymatchChar(G, '_')) goto l1426; if (!yy_Sp(G)) { goto l1426; } if (!yymatchChar(G, '_')) goto l1426; if (!yy_Sp(G)) { goto l1426; } if (!yymatchChar(G, '_')) goto l1426; - l1434:; - { int yypos1435= G->pos, yythunkpos1435= G->thunkpos; if (!yy_Sp(G)) { goto l1435; } if (!yymatchChar(G, '_')) goto l1435; goto l1434; - l1435:; G->pos= yypos1435; G->thunkpos= yythunkpos1435; - } - } - l1427:; if (!yy_Sp(G)) { goto l1426; } if (!yy_Newline(G)) { goto l1426; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1426; if (!yy_BlankLine(G)) { goto l1426; } - l1436:; - { int yypos1437= G->pos, yythunkpos1437= G->thunkpos; if (!yy_BlankLine(G)) { goto l1437; } goto l1436; - l1437:; G->pos= yypos1437; G->thunkpos= yythunkpos1437; - } yyDo(G, yy_1_HorizontalRule, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HorizontalRule", G->buf+G->pos)); - return 1; - l1426:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HorizontalRule", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Reference(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 3, 0); - yyprintf((stderr, "%s\n", "Reference")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1438; if (!yy_LocMarker(G)) { goto l1438; } yyDo(G, yySet, -3, 0); if (!yy_NonindentSpace(G)) { goto l1438; } - { int yypos1439= G->pos, yythunkpos1439= G->thunkpos; if (!yymatchString(G, "[]")) goto l1439; goto l1438; - l1439:; G->pos= yypos1439; G->thunkpos= yythunkpos1439; - } if (!yy_Label(G)) { goto l1438; } yyDo(G, yySet, -2, 0); if (!yymatchChar(G, ':')) goto l1438; if (!yy_Spnl(G)) { goto l1438; } if (!yy_RefSrc(G)) { goto l1438; } yyDo(G, yySet, -1, 0); if (!yy_RefTitle(G)) { goto l1438; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1438; if (!yy_BlankLine(G)) { goto l1438; } - l1440:; - { int yypos1441= G->pos, yythunkpos1441= G->thunkpos; if (!yy_BlankLine(G)) { goto l1441; } goto l1440; - l1441:; G->pos= yypos1441; G->thunkpos= yythunkpos1441; - } yyDo(G, yy_1_Reference, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Reference", G->buf+G->pos)); yyDo(G, yyPop, 3, 0); - return 1; - l1438:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Reference", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Note(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Note")); yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_NOTES) )) goto l1442; if (!yy_NonindentSpace(G)) { goto l1442; } if (!yy_RawNoteReference(G)) { goto l1442; } if (!yymatchChar(G, ':')) goto l1442; if (!yy_Sp(G)) { goto l1442; } if (!yy_RawNoteBlock(G)) { goto l1442; } - l1443:; - { int yypos1444= G->pos, yythunkpos1444= G->thunkpos; - { int yypos1445= G->pos, yythunkpos1445= G->thunkpos; if (!yy_Indent(G)) { goto l1444; } G->pos= yypos1445; G->thunkpos= yythunkpos1445; - } if (!yy_RawNoteBlock(G)) { goto l1444; } goto l1443; - l1444:; G->pos= yypos1444; G->thunkpos= yythunkpos1444; - } - yyprintf((stderr, " ok %s @ %s\n", "Note", G->buf+G->pos)); - return 1; - l1442:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Note", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Verbatim(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "Verbatim")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1446; if (!yy_LocMarker(G)) { goto l1446; } yyDo(G, yySet, -1, 0); if (!yy_VerbatimChunk(G)) { goto l1446; } - l1447:; - { int yypos1448= G->pos, yythunkpos1448= G->thunkpos; if (!yy_VerbatimChunk(G)) { goto l1448; } goto l1447; - l1448:; G->pos= yypos1448; G->thunkpos= yythunkpos1448; - } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1446; yyDo(G, yy_1_Verbatim, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Verbatim", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1446:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Verbatim", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_BlockQuote(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "BlockQuote")); if (!yy_BlockQuoteRaw(G)) { goto l1449; } yyDo(G, yySet, -1, 0); yyDo(G, yy_1_BlockQuote, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "BlockQuote", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1449:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "BlockQuote", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_BlankLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "BlankLine")); if (!yy_Sp(G)) { goto l1450; } if (!yy_Newline(G)) { goto l1450; } - yyprintf((stderr, " ok %s @ %s\n", "BlankLine", G->buf+G->pos)); - return 1; - l1450:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "BlankLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_LocMarker(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "LocMarker")); - { int yypos1452= G->pos, yythunkpos1452= G->thunkpos; if (!yymatchDot(G)) goto l1451; G->pos= yypos1452; G->thunkpos= yythunkpos1452; - } yyDo(G, yy_1_LocMarker, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "LocMarker", G->buf+G->pos)); - return 1; - l1451:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "LocMarker", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Block(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Block")); - l1454:; - { int yypos1455= G->pos, yythunkpos1455= G->thunkpos; if (!yy_BlankLine(G)) { goto l1455; } goto l1454; - l1455:; G->pos= yypos1455; G->thunkpos= yythunkpos1455; - } - { int yypos1456= G->pos, yythunkpos1456= G->thunkpos; if (!yy_BlockQuote(G)) { goto l1457; } goto l1456; - l1457:; G->pos= yypos1456; G->thunkpos= yythunkpos1456; if (!yy_Verbatim(G)) { goto l1458; } goto l1456; - l1458:; G->pos= yypos1456; G->thunkpos= yythunkpos1456; if (!yy_Note(G)) { goto l1459; } goto l1456; - l1459:; G->pos= yypos1456; G->thunkpos= yythunkpos1456; if (!yy_Reference(G)) { goto l1460; } goto l1456; - l1460:; G->pos= yypos1456; G->thunkpos= yythunkpos1456; if (!yy_HorizontalRule(G)) { goto l1461; } goto l1456; - l1461:; G->pos= yypos1456; G->thunkpos= yythunkpos1456; if (!yy_Heading(G)) { goto l1462; } goto l1456; - l1462:; G->pos= yypos1456; G->thunkpos= yythunkpos1456; if (!yy_OrderedList(G)) { goto l1463; } goto l1456; - l1463:; G->pos= yypos1456; G->thunkpos= yythunkpos1456; if (!yy_BulletList(G)) { goto l1464; } goto l1456; - l1464:; G->pos= yypos1456; G->thunkpos= yythunkpos1456; if (!yy_HtmlBlock(G)) { goto l1465; } goto l1456; - l1465:; G->pos= yypos1456; G->thunkpos= yythunkpos1456; if (!yy_StyleBlock(G)) { goto l1466; } goto l1456; - l1466:; G->pos= yypos1456; G->thunkpos= yythunkpos1456; if (!yy_Para(G)) { goto l1467; } goto l1456; - l1467:; G->pos= yypos1456; G->thunkpos= yythunkpos1456; if (!yy_Plain(G)) { goto l1453; } - } - l1456:; - yyprintf((stderr, " ok %s @ %s\n", "Block", G->buf+G->pos)); - return 1; - l1453:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Block", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Doc(GREG *G) -{ - yyprintf((stderr, "%s\n", "Doc")); - l1469:; - { int yypos1470= G->pos, yythunkpos1470= G->thunkpos; if (!yy_Block(G)) { goto l1470; } goto l1469; - l1470:; G->pos= yypos1470; G->thunkpos= yythunkpos1470; - } - yyprintf((stderr, " ok %s @ %s\n", "Doc", G->buf+G->pos)); - return 1; -} - -#ifndef YY_PART - -typedef int (*yyrule)(GREG *G); - -YY_PARSE(int) YY_NAME(parse_from)(GREG *G, yyrule yystart) -{ - int yyok; - if (!G->buflen) - { - G->buflen= YY_BUFFER_START_SIZE; - G->buf= (char *)YY_ALLOC(G->buflen, G->data); - G->textlen= YY_BUFFER_START_SIZE; - G->text= (char *)YY_ALLOC(G->textlen, G->data); - G->thunkslen= YY_STACK_SIZE; - G->thunks= (yythunk *)YY_ALLOC(sizeof(yythunk) * G->thunkslen, G->data); - G->valslen= YY_STACK_SIZE; - G->vals= (YYSTYPE*)YY_ALLOC(sizeof(YYSTYPE) * G->valslen, G->data); - G->begin= G->end= G->pos= G->limit= G->thunkpos= 0; - } - G->pos = 0; - G->begin= G->end= G->pos; - G->thunkpos= 0; - G->val= G->vals; - yyok= yystart(G); - if (yyok) yyDone(G); - yyCommit(G); - return yyok; - (void)yyrefill(NULL); - (void)yymatchDot(NULL); - (void)yymatchChar(NULL, 0); - (void)yymatchString(NULL, NULL); - (void)yymatchClass(NULL, NULL); - (void)yyDo(NULL, NULL, 0, 0); - (void)yyText(NULL, 0, 0); - (void)yyDone(NULL); - (void)yyCommit(NULL); - (void)yyAccept(NULL, 0); - (void)yyPush(NULL, NULL, 0, NULL, NULL); - (void)yyPop(NULL, NULL, 0, NULL, NULL); - (void)yySet(NULL, NULL, 0, NULL, NULL); -} - -YY_PARSE(int) YY_NAME(parse)(GREG *G) -{ - return YY_NAME(parse_from)(G, yy_Doc); -} - -YY_PARSE(GREG *) YY_NAME(parse_new)(YY_XTYPE data) -{ - GREG *G = (GREG *)YY_CALLOC(1, sizeof(GREG), G->data); - G->data = data; - return G; -} - -YY_PARSE(void) YY_NAME(parse_free)(GREG *G) -{ - YY_FREE(G->buf); - YY_FREE(G->text); - YY_FREE(G->thunks); - YY_FREE(G->vals); - YY_FREE(G); -} - -#endif - - - - -/* PEG Markdown Highlight - * Copyright 2011-2016 Ali Rantakari -- http://hasseg.org - * Licensed under the GPL2+ and MIT licenses (see LICENSE for more info). - * - * pmh_parser_foot.c - * - * Code to be appended to the end of the parser code generated from the - * PEG grammar. - */ - - -static void _parse(parser_data *p_data, yyrule start_rule) -{ - GREG *g = YY_NAME(parse_new)(p_data); - if (start_rule == NULL) - YY_NAME(parse)(g); - else - YY_NAME(parse_from)(g, start_rule); - YY_NAME(parse_free)(g); - - pmh_PRINTF("\n\n"); -} - -static void parse_markdown(parser_data *p_data) -{ - pmh_PRINTF("\nPARSING DOCUMENT: "); - - _parse(p_data, NULL); -} - -static void parse_references(parser_data *p_data) -{ - pmh_PRINTF("\nPARSING REFERENCES: "); - - p_data->parsing_only_references = true; - _parse(p_data, yy_References); - p_data->parsing_only_references = false; - - p_data->references = p_data->head_elems[pmh_REFERENCE]; - p_data->head_elems[pmh_REFERENCE] = NULL; -} - diff --git a/peg-highlight/pmh_parser.h b/peg-highlight/pmh_parser.h deleted file mode 100644 index 78086cab..00000000 --- a/peg-highlight/pmh_parser.h +++ /dev/null @@ -1,91 +0,0 @@ -/* PEG Markdown Highlight - * Copyright 2011-2016 Ali Rantakari -- http://hasseg.org - * Licensed under the GPL2+ and MIT licenses (see LICENSE for more info). - * - * pmh_parser.h - */ - -#ifdef Q_CC_GNU -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif - -/** \file -* \brief Parser public interface. -*/ - -#ifndef __cplusplus -#include -#endif - -#include -#include -#include "pmh_definitions.h" - - -/** -* \brief Parse Markdown text, return elements -* -* Parses the given Markdown text and returns the results as an -* array of linked lists of elements, indexed by type. -* -* \param[in] text The Markdown text to parse for highlighting. -* \param[in] extensions The extensions to use in parsing (a bitfield -* of pmh_extensions values). -* \param[out] out_result A pmh_element array, indexed by type, containing -* the results of the parsing (linked lists of elements). -* You must pass this to pmh_free_elements() when it's -* not needed anymore. -* -* \sa pmh_element_type -*/ -void pmh_markdown_to_elements(char *text, int extensions, - pmh_element **out_result[]); - -/** -* \brief Sort elements in list by start offset. -* -* Sorts the linked lists of elements in the list returned by -* pmh_markdown_to_elements() by their start offsets (pos). -* -* \param[in] element_lists Array of linked lists of elements (output -* from pmh_markdown_to_elements()). -* -* \sa pmh_markdown_to_elements -* \sa pmh_element::pos -*/ -void pmh_sort_elements_by_pos(pmh_element *element_lists[]); - -/** -* \brief Free pmh_element array -* -* Frees an pmh_element array returned by pmh_markdown_to_elements(). -* -* \param[in] elems The pmh_element array resulting from calling -* pmh_markdown_to_elements(). -* -* \sa pmh_markdown_to_elements -*/ -void pmh_free_elements(pmh_element **elems); - -/** -* \brief Get element type name -* -* \param[in] type The type value to get the name for. -* -* \return The name of the given type as a null-terminated string. -* -* \sa pmh_element_type -*/ -char *pmh_element_name_from_type(pmh_element_type type); - -/** -* \brief Get element type from a name -* -* \param[in] name The name of the type. -* -* \return The element type corresponding to the given name. -* -* \sa pmh_element_type -*/ -pmh_element_type pmh_element_type_from_name(char *name); - diff --git a/peg-highlight/pmh_styleparser.c b/peg-highlight/pmh_styleparser.c deleted file mode 100644 index 4c577c90..00000000 --- a/peg-highlight/pmh_styleparser.c +++ /dev/null @@ -1,934 +0,0 @@ -/* PEG Markdown Highlight - * Copyright 2011-2016 Ali Rantakari -- http://hasseg.org - * Licensed under the GPL2+ and MIT licenses (see LICENSE for more info). - * - * styleparser.c - * - * Parser for custom syntax highlighting stylesheets. - */ - -#include -#include -#include -#include -#include - -#include "pmh_styleparser.h" -#include "pmh_parser.h" - - -#if pmh_DEBUG_OUTPUT -#define pmhsp_PRINTF(x, ...) fprintf(stderr, x, ##__VA_ARGS__) -#else -#define pmhsp_PRINTF(x, ...) -#endif - - -// vasprintf is not in the C standard nor in POSIX so we provide our own -static int our_vasprintf(char **strptr, const char *fmt, va_list argptr) -{ - int ret; - va_list argptr2; - *strptr = NULL; - - va_copy(argptr2, argptr); - ret = vsnprintf(NULL, 0, fmt, argptr2); - if (ret <= 0) - return ret; - - *strptr = (char *)malloc(ret+1); - if (*strptr == NULL) - return -1; - - va_copy(argptr2, argptr); - ret = vsnprintf(*strptr, ret+1, fmt, argptr2); - - return ret; -} - - - -// Parsing context data -typedef struct -{ - char *input; - void (*error_callback)(char*,int,void*); - void *error_callback_context; - int styles_pos; - pmh_style_collection *styles; -} style_parser_data; - -typedef struct raw_attribute -{ - char *name; - char *value; - int line_number; - struct raw_attribute *next; -} raw_attribute; - -static raw_attribute *new_raw_attribute(char *name, char *value, - int line_number) -{ - raw_attribute *v = (raw_attribute *)malloc(sizeof(raw_attribute)); - v->name = name; - v->value = value; - v->line_number = line_number; - v->next = NULL; - return v; -} - -static void free_raw_attributes(raw_attribute *list) -{ - raw_attribute *cur = list; - while (cur != NULL) - { - raw_attribute *pattr = NULL; - if (cur->name != NULL) free(cur->name); - if (cur->value != NULL) free(cur->value); - pattr = cur; - cur = cur->next; - free(pattr); - } -} - - -static void report_error(style_parser_data *p_data, - int line_number, char *str, ...) -{ - va_list argptr; - if (p_data->error_callback == NULL) - return; - - va_start(argptr, str); - char *errmsg; - our_vasprintf(&errmsg, str, argptr); - va_end(argptr); - p_data->error_callback(errmsg, line_number, - p_data->error_callback_context); - free(errmsg); -} - - - -static char *trim_str(char *str) -{ - while (isspace(*str)) - str++; - if (*str == '\0') - return str; - char *end = str + strlen(str) - 1; - while (end > str && isspace(*end)) - end--; - *(end+1) = '\0'; - return str; -} - -static char *trim_str_dup(char *str) -{ - size_t start = 0; - while (isspace(*(str + start))) - start++; - size_t end = strlen(str) - 1; - while (start < end && isspace(*(str + end))) - end--; - - size_t len = end - start + 1; - char *ret = (char *)malloc(sizeof(char)*len + 1); - *ret = '\0'; - strncat(ret, (str + start), len); - - return ret; -} - -static char *strcpy_lower(char *str) -{ - char *low = strdup(str); - int i; - int len = strlen(str); - for (i = 0; i < len; i++) - *(low+i) = tolower(*(low+i)); - return low; -} - -static char *standardize_str(char *str) -{ - return strcpy_lower(trim_str(str)); -} - - - - -static pmh_attr_argb_color *new_argb_color(int r, int g, int b, int a) -{ - pmh_attr_argb_color *c = (pmh_attr_argb_color *) - malloc(sizeof(pmh_attr_argb_color)); - c->red = r; c->green = g; c->blue = b; c->alpha = a; - return c; -} -static pmh_attr_argb_color *new_argb_from_hex(long long hex, bool has_alpha) -{ - // 0xaarrggbb - int a = has_alpha ? ((hex >> 24) & 0xFF) : 255; - int r = ((hex >> 16) & 0xFF); - int g = ((hex >> 8) & 0xFF); - int b = (hex & 0xFF); - return new_argb_color(r,g,b,a); -} -static pmh_attr_argb_color *new_argb_from_hex_str(style_parser_data *p_data, - int attr_line_number, - char *str) -{ - // "aarrggbb" - int len = strlen(str); - if (len != 6 && len != 8) { - report_error(p_data, attr_line_number, - "Value '%s' is not a valid color value: it should be a " - "hexadecimal number, 6 or 8 characters long.", - str); - return NULL; - } - char *endptr = NULL; - long long num = strtoll(str, &endptr, 16); - if (*endptr != '\0') { - report_error(p_data, attr_line_number, - "Value '%s' is not a valid color value: the character " - "'%c' is invalid. The color value should be a hexadecimal " - "number, 6 or 8 characters long.", - str, *endptr); - return NULL; - } - return new_argb_from_hex(num, (len == 8)); -} - -static pmh_attr_value *new_attr_value() -{ - return (pmh_attr_value *)malloc(sizeof(pmh_attr_value)); -} - -static pmh_attr_font_styles *new_font_styles() -{ - pmh_attr_font_styles *ret = (pmh_attr_font_styles *) - malloc(sizeof(pmh_attr_font_styles)); - ret->italic = false; - ret->bold = false; - ret->underlined = false; - return ret; -} - -static pmh_attr_font_size *new_font_size() -{ - pmh_attr_font_size *ret = (pmh_attr_font_size *) - malloc(sizeof(pmh_attr_font_size)); - ret->is_relative = false; - ret->size_pt = 0; - return ret; -} - -static pmh_style_attribute *new_attr(char *name, pmh_attr_type type) -{ - pmh_style_attribute *attr = (pmh_style_attribute *)malloc(sizeof(pmh_style_attribute)); - attr->name = strdup(name); - attr->type = type; - attr->next = NULL; - return attr; -} - -static void free_style_attributes(pmh_style_attribute *list) -{ - pmh_style_attribute *cur = list; - while (cur != NULL) - { - if (cur->name != NULL) - free(cur->name); - if (cur->value != NULL) - { - if (cur->type == pmh_attr_type_foreground_color - || cur->type == pmh_attr_type_background_color - || cur->type == pmh_attr_type_caret_color - || cur->type == pmh_attr_type_strike_color) - free(cur->value->argb_color); - else if (cur->type == pmh_attr_type_font_family) - free(cur->value->font_family); - else if (cur->type == pmh_attr_type_font_style) - free(cur->value->font_styles); - else if (cur->type == pmh_attr_type_font_size_pt) - free(cur->value->font_size); - else if (cur->type == pmh_attr_type_other) - free(cur->value->string); - free(cur->value); - } - pmh_style_attribute *pattr = cur; - cur = cur->next; - free(pattr); - } -} - - - - - -#define IF_ATTR_NAME(x) if (strcmp(x, name) == 0) -pmh_attr_type pmh_attr_type_from_name(char *name) -{ - IF_ATTR_NAME("color") return pmh_attr_type_foreground_color; - else IF_ATTR_NAME("foreground") return pmh_attr_type_foreground_color; - else IF_ATTR_NAME("foreground-color") return pmh_attr_type_foreground_color; - else IF_ATTR_NAME("background") return pmh_attr_type_background_color; - else IF_ATTR_NAME("background-color") return pmh_attr_type_background_color; - else IF_ATTR_NAME("caret") return pmh_attr_type_caret_color; - else IF_ATTR_NAME("caret-color") return pmh_attr_type_caret_color; - else IF_ATTR_NAME("strike") return pmh_attr_type_strike_color; - else IF_ATTR_NAME("strike-color") return pmh_attr_type_strike_color; - else IF_ATTR_NAME("font-size") return pmh_attr_type_font_size_pt; - else IF_ATTR_NAME("font-family") return pmh_attr_type_font_family; - else IF_ATTR_NAME("font-style") return pmh_attr_type_font_style; - return pmh_attr_type_other; -} - -char *pmh_attr_name_from_type(pmh_attr_type type) -{ - switch (type) - { - case pmh_attr_type_foreground_color: - return "foreground-color"; break; - case pmh_attr_type_background_color: - return "background-color"; break; - case pmh_attr_type_caret_color: - return "caret-color"; break; - case pmh_attr_type_strike_color: - return "strike-color"; break; - case pmh_attr_type_font_size_pt: - return "font-size"; break; - case pmh_attr_type_font_family: - return "font-family"; break; - case pmh_attr_type_font_style: - return "font-style"; break; - default: - return "unknown"; - } -} - - -typedef struct multi_value -{ - char *value; - size_t length; - int line_number; - struct multi_value *next; -} multi_value; - -static multi_value *split_multi_value(char *input, char separator) -{ - multi_value *head = NULL; - multi_value *tail = NULL; - - char *c = input; - while (*c != '\0') - { - size_t i; - for (i = 0; (*(c+i) != '\0' && *(c+i) != separator); i++); - - multi_value *mv = (multi_value *)malloc(sizeof(multi_value)); - mv->value = (char *)malloc(sizeof(char)*i + 1); - mv->length = i; - mv->line_number = 0; - mv->next = NULL; - *mv->value = '\0'; - strncat(mv->value, c, i); - - if (head == NULL) { - head = mv; - tail = mv; - } else { - tail->next = mv; - tail = mv; - } - - if (*(c+i) == separator) - i++; - c += i; - } - - return head; -} - -static void free_multi_value(multi_value *val) -{ - multi_value *cur = val; - while (cur != NULL) - { - multi_value *pvalue = cur; - multi_value *next_cur = cur->next; - free(pvalue->value); - free(pvalue); - cur = next_cur; - } -} - - - - -#define EQUALS(a,b) (strcmp(a, b) == 0) - -static pmh_style_attribute *interpret_attributes(style_parser_data *p_data, - pmh_element_type lang_element_type, - raw_attribute *raw_attributes) -{ - pmh_style_attribute *attrs = NULL; - - raw_attribute *cur = raw_attributes; - while (cur != NULL) - { - pmh_attr_type atype = pmh_attr_type_from_name(cur->name); - pmh_style_attribute *attr = new_attr(cur->name, atype); - attr->lang_element_type = lang_element_type; - attr->value = new_attr_value(); - - if (atype == pmh_attr_type_foreground_color - || atype == pmh_attr_type_background_color - || atype == pmh_attr_type_caret_color - || atype == pmh_attr_type_strike_color) - { - char *hexstr = trim_str(cur->value); - // new_argb_from_hex_str() reports conversion errors - attr->value->argb_color = - new_argb_from_hex_str(p_data, cur->line_number, hexstr); - if (attr->value->argb_color == NULL) { - free_style_attributes(attr); - attr = NULL; - } - } - else if (atype == pmh_attr_type_font_size_pt) - { - pmh_attr_font_size *fs = new_font_size(); - attr->value->font_size = fs; - - char *trimmed_value = trim_str_dup(cur->value); - - fs->is_relative = (*trimmed_value == '+' || *trimmed_value == '-'); - char *endptr = NULL; - fs->size_pt = (int)strtol(cur->value, &endptr, 10); - if (endptr == cur->value) { - report_error(p_data, cur->line_number, - "Value '%s' is invalid for attribute '%s'", - cur->value, cur->name); - free_style_attributes(attr); - attr = NULL; - } - - free(trimmed_value); - } - else if (atype == pmh_attr_type_font_family) - { - attr->value->font_family = trim_str_dup(cur->value); - } - else if (atype == pmh_attr_type_font_style) - { - attr->value->font_styles = new_font_styles(); - multi_value *values = split_multi_value(cur->value, ','); - multi_value *value_cur = values; - while (value_cur != NULL) - { - char *standardized_value = standardize_str(value_cur->value); - - if (EQUALS(standardized_value, "italic")) - attr->value->font_styles->italic = true; - else if (EQUALS(standardized_value, "bold")) - attr->value->font_styles->bold = true; - else if (EQUALS(standardized_value, "underlined")) - attr->value->font_styles->underlined = true; - else { - report_error(p_data, cur->line_number, - "Value '%s' is invalid for attribute '%s'", - standardized_value, cur->name); - } - - free(standardized_value); - value_cur = value_cur->next; - } - free_multi_value(values); - } - else if (atype == pmh_attr_type_other) - { - attr->value->string = trim_str_dup(cur->value); - } - - if (attr != NULL) { - // add to linked list - attr->next = attrs; - attrs = attr; - } - - cur = cur->next; - } - - return attrs; -} - - -static void interpret_and_add_style(style_parser_data *p_data, - char *style_rule_name, - int style_rule_line_number, - raw_attribute *raw_attributes) -{ - bool isEditorType = false; - bool isCurrentLineType = false; - bool isSelectionType = false; - pmh_element_type type = pmh_element_type_from_name(style_rule_name); - if (type == pmh_NO_TYPE) - { - if (EQUALS(style_rule_name, "editor")) - isEditorType = true, type = pmh_NO_TYPE; - else if (EQUALS(style_rule_name, "editor-current-line")) - isCurrentLineType = true, type = pmh_NO_TYPE; - else if (EQUALS(style_rule_name, "editor-selection")) - isSelectionType = true, type = pmh_NO_TYPE; - else { - report_error(p_data, style_rule_line_number, - "Style rule '%s' is not a language element type name or " - "one of the following: 'editor', 'editor-current-line', " - "'editor-selection'", - style_rule_name); - return; - } - } - pmh_style_attribute *attrs = interpret_attributes(p_data, type, raw_attributes); - if (isEditorType) - p_data->styles->editor_styles = attrs; - else if (isCurrentLineType) - p_data->styles->editor_current_line_styles = attrs; - else if (isSelectionType) - p_data->styles->editor_selection_styles = attrs; - else - p_data->styles->element_styles[(p_data->styles_pos)++] = attrs; -} - - - - - - - -static bool char_is_whitespace(char c) -{ - return (c == ' ' || c == '\t'); -} - -static bool char_begins_linecomment(char c) -{ - return (c == '#'); -} - -static bool line_is_comment(multi_value *line) -{ - char *c; - for (c = line->value; *c != '\0'; c++) - { - if (!char_is_whitespace(*c)) - return char_begins_linecomment(*c); - } - return false; -} - -static bool line_is_empty(multi_value *line) -{ - char *c; - for (c = line->value; *c != '\0'; c++) - { - if (!char_is_whitespace(*c)) - return false; - } - return true; -} - - - -typedef struct block -{ - multi_value *lines; - struct block *next; -} block; - -static block *new_block() -{ - block *ret = (block *)malloc(sizeof(block)); - ret->next = NULL; - ret->lines = NULL; - return ret; -} - -static void free_blocks(block *val) -{ - block *cur = val; - while (cur != NULL) - { - block *pblock = cur; - block *next = pblock->next; - free_multi_value(pblock->lines); - free(pblock); - cur = next; - } -} - -static block *get_blocks(char *input) -{ - block *head = NULL; - block *tail = NULL; - block *current_block = NULL; - - multi_value *discarded_lines = NULL; - - int line_number_counter = 1; - - multi_value *lines = split_multi_value(input, '\n'); - multi_value *previous_line = NULL; - multi_value *line_cur = lines; - while (line_cur != NULL) - { - bool discard_line = false; - - line_cur->line_number = line_number_counter++; - - if (line_is_empty(line_cur)) - { - discard_line = true; - - if (current_block != NULL) - { - // terminate block - if (tail != current_block) - tail->next = current_block; - tail = current_block; - current_block = NULL; - previous_line->next = NULL; - } - } - else if (line_is_comment(line_cur)) - { - // Do not discard (i.e. free()) comment lines within blocks: - if (current_block == NULL) - discard_line = true; - } - else - { - if (current_block == NULL) - { - // start block - current_block = new_block(); - current_block->lines = line_cur; - if (previous_line != NULL) - previous_line->next = NULL; - } - if (head == NULL) { - head = current_block; - tail = current_block; - } - } - - multi_value *next_cur = line_cur->next; - previous_line = (discard_line) ? NULL : line_cur; - - if (discard_line) { - line_cur->next = discarded_lines; - discarded_lines = line_cur; - } - - line_cur = next_cur; - } - - if (current_block != NULL && tail != current_block) - tail->next = current_block; - - free_multi_value(discarded_lines); - - return head; -} - - -#define ASSIGNMENT_OP_UITEXT "':' or '='" -#define IS_ASSIGNMENT_OP(c) ((c) == ':' || (c) == '=') -#define IS_STYLE_RULE_NAME_CHAR(c) \ - ( (c) != '\0' && !isspace(c) \ - && !char_begins_linecomment(c) && !IS_ASSIGNMENT_OP(c) ) -#define IS_ATTRIBUTE_NAME_CHAR(c) \ - ( (c) != '\0' && !char_begins_linecomment(c) && !IS_ASSIGNMENT_OP(c) ) -#define IS_ATTRIBUTE_VALUE_CHAR(c) \ - ( (c) != '\0' && !char_begins_linecomment(c) ) - -static char *get_style_rule_name(multi_value *line) -{ - char *str = line->value; - - // Scan past leading whitespace: - size_t start_index; - for (start_index = 0; - (*(str+start_index) != '\0' && isspace(*(str+start_index))); - start_index++); - - // Scan until style rule name characters end: - size_t value_end_index; - for (value_end_index = start_index; - IS_STYLE_RULE_NAME_CHAR(*(str + value_end_index)); - value_end_index++); - - // Copy style rule name: - size_t value_len = value_end_index - start_index; - char *value = (char *)malloc(sizeof(char)*value_len + 1); - *value = '\0'; - strncat(value, (str + start_index), value_len); - - return value; -} - -static bool parse_attribute_line(style_parser_data *p_data, multi_value *line, - char **out_attr_name, char **out_attr_value) -{ - char *str = line->value; - - // Scan past leading whitespace: - size_t name_start_index; - for (name_start_index = 0; - ( *(str+name_start_index) != '\0' && - isspace(*(str+name_start_index)) ); - name_start_index++); - - // Scan until attribute name characters end: - size_t name_end_index; - for (name_end_index = name_start_index; - IS_ATTRIBUTE_NAME_CHAR(*(str + name_end_index)); - name_end_index++); - // Scan backwards to trim trailing whitespace off: - while (name_start_index < name_end_index - && isspace(*(str + name_end_index - 1))) - name_end_index--; - - // Scan until just after the first assignment operator: - size_t assignment_end_index; - for (assignment_end_index = name_end_index; - ( *(str + assignment_end_index) != '\0' && - !IS_ASSIGNMENT_OP(*(str + assignment_end_index)) ); - assignment_end_index++); - - // Scan over the found assignment operator, or report error: - if (IS_ASSIGNMENT_OP(*(str + assignment_end_index))) - assignment_end_index++; - else - { - report_error(p_data, line->line_number, - "Invalid attribute definition: str does not contain " - "an assignment operator (%s): '%s'", - ASSIGNMENT_OP_UITEXT, str); - return false; - } - - size_t value_start_index = assignment_end_index; - // Scan until attribute value characters end: - size_t value_end_index; - for (value_end_index = value_start_index; - IS_ATTRIBUTE_VALUE_CHAR(*(str + value_end_index)); - value_end_index++); - - // Copy attribute name: - size_t name_len = name_end_index - name_start_index; - char *attr_name = (char *)malloc(sizeof(char)*name_len + 1); - *attr_name = '\0'; - strncat(attr_name, (str + name_start_index), name_len); - *out_attr_name = attr_name; - - // Copy attribute value: - size_t attr_value_len = value_end_index - assignment_end_index; - char *attr_value_str = (char *)malloc(sizeof(char)*attr_value_len + 1); - *attr_value_str = '\0'; - strncat(attr_value_str, (str + assignment_end_index), attr_value_len); - *out_attr_value = attr_value_str; - - return true; -} - - -#define HAS_UTF8_BOM(x) ( ((*x & 0xFF) == 0xEF)\ - && ((*(x+1) & 0xFF) == 0xBB)\ - && ((*(x+2) & 0xFF) == 0xBF) ) - -// - Removes UTF-8 BOM -// - Standardizes line endings to \n -static char *strcpy_preformat_style(char *str) -{ - char *new_str = (char *)malloc(sizeof(char) * strlen(str) + 1); - - char *c = str; - int i = 0; - - if (HAS_UTF8_BOM(c)) - c += 3; - - while (*c != '\0') - { - if (*c == '\r' && *(c+1) == '\n') - { - *(new_str+i) = '\n'; - i++; - c += 2; - } - else if (*c == '\r') - { - *(new_str+i) = '\n'; - i++; - c++; - } - else - { - *(new_str+i) = *c; - i++; - c++; - } - } - *(new_str+i) = '\0'; - - return new_str; -} - - - -static void _sty_parse(style_parser_data *p_data) -{ - // We don't have to worry about leaking the original p_data->input; - // the user of the library is responsible for that: - p_data->input = strcpy_preformat_style(p_data->input); - - block *blocks = get_blocks(p_data->input); - - block *block_cur = blocks; - while (block_cur != NULL) - { - raw_attribute *attributes_head = NULL; - raw_attribute *attributes_tail = NULL; - - pmhsp_PRINTF("Block:\n"); - multi_value *header_line = block_cur->lines; - if (header_line == NULL) { - block_cur = block_cur->next; - continue; - } - - pmhsp_PRINTF(" Head line (len %ld): '%s'\n", - header_line->length, header_line->value); - char *style_rule_name = get_style_rule_name(header_line); - pmhsp_PRINTF(" Style rule name: '%s'\n", style_rule_name); - - multi_value *attr_line_cur = header_line->next; - if (attr_line_cur == NULL) - report_error(p_data, header_line->line_number, - "No style attributes defined for style rule '%s'", - style_rule_name); - - while (attr_line_cur != NULL) - { - if (line_is_comment(attr_line_cur)) - { - attr_line_cur = attr_line_cur->next; - continue; - } - - pmhsp_PRINTF(" Attr line (len %ld): '%s'\n", - attr_line_cur->length, attr_line_cur->value); - char *attr_name_str; - char *attr_value_str; - bool success = parse_attribute_line(p_data, - attr_line_cur, - &attr_name_str, - &attr_value_str); - if (success) - { - pmhsp_PRINTF(" Attr: '%s' Value: '%s'\n", - attr_name_str, attr_value_str); - raw_attribute *attribute = - new_raw_attribute(attr_name_str, attr_value_str, - attr_line_cur->line_number); - if (attributes_head == NULL) { - attributes_head = attribute; - attributes_tail = attribute; - } else { - attributes_tail->next = attribute; - attributes_tail = attribute; - } - } - - attr_line_cur = attr_line_cur->next; - } - - if (attributes_head != NULL) - { - interpret_and_add_style(p_data, style_rule_name, - header_line->line_number, attributes_head); - free_raw_attributes(attributes_head); - } - - free(style_rule_name); - - block_cur = block_cur->next; - } - - free_blocks(blocks); - free(p_data->input); -} - - - -static pmh_style_collection *new_style_collection() -{ - pmh_style_collection *sc = (pmh_style_collection *) - malloc(sizeof(pmh_style_collection)); - - sc->element_styles = (pmh_style_attribute**) - malloc(sizeof(pmh_style_attribute*) - * pmh_NUM_LANG_TYPES); - int i; - for (i = 0; i < pmh_NUM_LANG_TYPES; i++) - sc->element_styles[i] = NULL; - - sc->editor_styles = NULL; - sc->editor_current_line_styles = NULL; - sc->editor_selection_styles = NULL; - - return sc; -} - -void pmh_free_style_collection(pmh_style_collection *coll) -{ - free_style_attributes(coll->editor_styles); - free_style_attributes(coll->editor_current_line_styles); - free_style_attributes(coll->editor_selection_styles); - int i; - for (i = 0; i < pmh_NUM_LANG_TYPES; i++) - free_style_attributes(coll->element_styles[i]); - free(coll->element_styles); - free(coll); -} - -static style_parser_data *new_style_parser_data(char *input) -{ - style_parser_data *p_data = (style_parser_data*) - malloc(sizeof(style_parser_data)); - p_data->input = input; - p_data->styles_pos = 0; - p_data->styles = new_style_collection(); - return p_data; -} - -pmh_style_collection *pmh_parse_styles(char *input, - void(*error_callback)(char*,int,void*), - void *error_callback_context) -{ - style_parser_data *p_data = new_style_parser_data(input); - p_data->error_callback = error_callback; - p_data->error_callback_context = error_callback_context; - - _sty_parse(p_data); - - pmh_style_collection *ret = p_data->styles; - free(p_data); - return ret; -} - - diff --git a/peg-highlight/pmh_styleparser.h b/peg-highlight/pmh_styleparser.h deleted file mode 100644 index 96afe3c1..00000000 --- a/peg-highlight/pmh_styleparser.h +++ /dev/null @@ -1,148 +0,0 @@ -/* PEG Markdown Highlight - * Copyright 2011-2016 Ali Rantakari -- http://hasseg.org - * Licensed under the GPL2+ and MIT licenses (see LICENSE for more info). - * - * pmh_styleparser.h - * - * Public interface of a parser for custom syntax highlighting stylesheets. - */ - -/** \file -* \brief Style parser public interface. -*/ - -#include "pmh_definitions.h" -#include - -/** -* \brief Color (ARGB) attribute value. -* -* All values are 0-255. -*/ -typedef struct -{ - int red; /**< Red color component (0-255) */ - int green; /**< Green color component (0-255) */ - int blue; /**< Blue color component (0-255) */ - int alpha; /**< Alpha (opacity) color component (0-255) */ -} pmh_attr_argb_color; - -/** \brief Font style attribute value. */ -typedef struct -{ - bool italic; - bool bold; - bool underlined; -} pmh_attr_font_styles; - -/** \brief Font size attribute value. */ -typedef struct -{ - int size_pt; /**< The font point size */ - bool is_relative; /**< Whether the size is relative (i.e. size_pt points - larger than the default font) */ -} pmh_attr_font_size; - -/** \brief Style attribute types. */ -typedef enum -{ - pmh_attr_type_foreground_color, /**< Foreground color */ - pmh_attr_type_background_color, /**< Background color */ - pmh_attr_type_caret_color, /**< Caret (insertion point) color */ - pmh_attr_type_font_size_pt, /**< Font size (in points) */ - pmh_attr_type_font_family, /**< Font family */ - pmh_attr_type_font_style, /**< Font style */ - pmh_attr_type_strike_color, /**< Strike-through color */ - pmh_attr_type_other /**< Arbitrary custom attribute */ -} pmh_attr_type; - -/** -* \brief Style attribute value. -* -* Determine which member to access in this union based on the -* 'type' value of the pmh_style_attribute. -* -* \sa pmh_style_attribute -*/ -typedef union -{ - pmh_attr_argb_color *argb_color; /**< ARGB color */ - pmh_attr_font_styles *font_styles; /**< Font styles */ - pmh_attr_font_size *font_size; /**< Font size */ - char *font_family; /**< Font family */ - char *string; /**< Arbitrary custom string value - (use this if the attribute's type - is pmh_attr_type_other) */ -} pmh_attr_value; - -/** \brief Style attribute. */ -typedef struct pmh_style_attribute -{ - pmh_element_type lang_element_type; /**< The Markdown language element this - style applies to */ - pmh_attr_type type; /**< The type of the attribute */ - char *name; /**< The name of the attribute (if type - is pmh_attr_type_other, you can - use this value to determine what - the attribute is) */ - pmh_attr_value *value; /**< The value of the attribute */ - struct pmh_style_attribute *next; /**< Next attribute in linked list */ -} pmh_style_attribute; - -/** \brief Collection of styles. */ -typedef struct -{ - /** Styles that apply to the editor in general */ - pmh_style_attribute *editor_styles; - - /** Styles that apply to the line in the editor where the caret (insertion - point) resides */ - pmh_style_attribute *editor_current_line_styles; - - /** Styles that apply to the range of selected text in the editor */ - pmh_style_attribute *editor_selection_styles; - - /** Styles that apply to specific Markdown language elements */ - pmh_style_attribute **element_styles; -} pmh_style_collection; - - -/** -* \brief Parse stylesheet string, return style collection -* -* \param[in] input The stylesheet string to parse. -* \param[in] error_callback Callback function to be called when errors -* occur during parsing. The first argument -* to the callback function is the error -* message and the second one the line number -* in the original input where the error -* occurred. The last argument will always -* get the value you pass in for the -* error_callback_context argument to this -* function. -* Pass in NULL to suppress error reporting. -* \param[in] error_callback_context Arbitrary context pointer for the error -* callback function; will be passed in as -* the last argument to error_callback. -* -* \return A pmh_style_collection. You must pass this value to -* pmh_free_style_collection() when it's not needed anymore. -*/ -pmh_style_collection *pmh_parse_styles(char *input, - void(*error_callback)(char*,int,void*), - void *error_callback_context); - -/** -* \brief Free a pmh_style_collection. -* -* Frees a pmh_style_collection value returned by pmh_parse_styles(). -* -* \param[in] collection The collection to free. -*/ -void pmh_free_style_collection(pmh_style_collection *collection); - - -char *pmh_attr_name_from_type(pmh_attr_type type); - -pmh_attr_type pmh_attr_type_from_name(char *name); - diff --git a/peg-highlight/styles/error.style b/peg-highlight/styles/error.style deleted file mode 100644 index 4036ff9b..00000000 --- a/peg-highlight/styles/error.style +++ /dev/null @@ -1,8 +0,0 @@ -NONEXISTENT_TYPE -x: 3 - -STRONG -font-style: funkadelic, bold, snazzy -foreground: 13bx12 -background: 5 - diff --git a/peg-highlight/styles/fontsizes.style b/peg-highlight/styles/fontsizes.style deleted file mode 100644 index d6b40c5c..00000000 --- a/peg-highlight/styles/fontsizes.style +++ /dev/null @@ -1,87 +0,0 @@ -# Styles using 'Solarized' color scheme -# by Ethan Schoonover: http://ethanschoonover.com/solarized -# -# (dark background version) - -editor -foreground: 93a1a1 # base1 -background: 002b36 # base03 -caret: ffffff -font-size: 13 - -H1 -foreground: 6c71c4 # violet -font-style: bold -font-size: +6 - -H2 -foreground: 6c71c4 # violet -font-style: bold -font-size: +5 - -H3 -foreground: 6c71c4 # violet -font-size: +4 - -H4 -foreground: 268bd2 # blue -font-size: +3 - -H5 -foreground: 268bd2 # blue -font-size: +2 - -H6 -foreground: 268bd2 # blue -font-size: +1 - -HRULE -foreground: 586e75 # base01 - -LIST_BULLET -foreground: b58900 # yellow - -LIST_ENUMERATOR -foreground: b58900 # yellow - -LINK -foreground: 2aa198 # cyan - -AUTO_LINK_URL -foreground: 2aa198 # cyan - -AUTO_LINK_EMAIL -foreground: 2aa198 # cyan - -IMAGE -foreground: d33682 # magenta - -REFERENCE -foreground: 80b58900 # yellow, reduced alpha -font-size: -2 - -CODE -foreground: 859900 # green - -EMPH -foreground: cb4b16 # orange -font-style: italic - -STRONG -foreground: dc322f # red -font-style: bold - -HTML_ENTITY -foreground: 6c71c4 # violet - -COMMENT -foreground: 93a1a1 # base1 - -VERBATIM -foreground: 859900 # green - -BLOCKQUOTE -foreground: d33682 # magenta - -STRIKE -strike-color: 93a1a1 # base1 diff --git a/peg-highlight/styles/macoslineseparator.style b/peg-highlight/styles/macoslineseparator.style deleted file mode 100644 index b6b92559..00000000 --- a/peg-highlight/styles/macoslineseparator.style +++ /dev/null @@ -1 +0,0 @@ -# linecomment editor # comment foreground : 13ff13 background : 000000 # comment # linecomment STRONG: EMPH= # comment foreground: 00ff00 comment asd background: AB0000ff STRONG : dog: 1 # something cat: 4 font-style: underlined, Italic , BoLD #hi, hello font-size: 14pt font-family: Courier New, Times # linecomment BOO x: 3 editor-selection: foreground: abcdef background: abcdef editor-current-line: background: ffffff \ No newline at end of file diff --git a/peg-highlight/styles/playground.style b/peg-highlight/styles/playground.style deleted file mode 100644 index 464768d5..00000000 --- a/peg-highlight/styles/playground.style +++ /dev/null @@ -1,22 +0,0 @@ -editor : - foreground : 13ff13 - background : 000000 - caret: ffffff - -EMPH - font-style: italic - -STRONG - font-style: bold - -LINK - font-style: underlined - -editor-selection: - foreground: ff0000 - background: eeeeee - font-style: underlined - -editor-current-line: - background: ffffff - diff --git a/peg-highlight/styles/solarized-dark.style b/peg-highlight/styles/solarized-dark.style deleted file mode 100644 index 635d5b3e..00000000 --- a/peg-highlight/styles/solarized-dark.style +++ /dev/null @@ -1,79 +0,0 @@ -# Styles using 'Solarized' color scheme -# by Ethan Schoonover: http://ethanschoonover.com/solarized -# -# (dark background version) - -editor -foreground: 93a1a1 # base1 -background: 002b36 # base03 -caret: ffffff - -H1 -foreground: 6c71c4 # violet -font-style: bold - -H2 -foreground: 6c71c4 # violet -font-style: bold - -H3 -foreground: 6c71c4 # violet - -H4 -foreground: 268bd2 # blue - -H5 -foreground: 268bd2 # blue - -H6 -foreground: 268bd2 # blue - -HRULE -foreground: 586e75 # base01 - -LIST_BULLET -foreground: b58900 # yellow - -LIST_ENUMERATOR -foreground: b58900 # yellow - -LINK -foreground: 2aa198 # cyan - -AUTO_LINK_URL -foreground: 2aa198 # cyan - -AUTO_LINK_EMAIL -foreground: 2aa198 # cyan - -IMAGE -foreground: d33682 # magenta - -REFERENCE -foreground: 80b58900 # yellow, reduced alpha - -CODE -foreground: 859900 # green - -EMPH -foreground: cb4b16 # orange -font-style: italic - -STRONG -foreground: dc322f # red -font-style: bold - -HTML_ENTITY -foreground: 6c71c4 # violet - -COMMENT -foreground: 93a1a1 # base1 - -VERBATIM -foreground: 859900 # green - -BLOCKQUOTE -foreground: d33682 # magenta - -STRIKE -strike-color: 93a1a1 # base1 diff --git a/peg-highlight/styles/solarized-light.style b/peg-highlight/styles/solarized-light.style deleted file mode 100644 index 5d496177..00000000 --- a/peg-highlight/styles/solarized-light.style +++ /dev/null @@ -1,80 +0,0 @@ -# Styles using 'Solarized' color scheme -# by Ethan Schoonover: http://ethanschoonover.com/solarized -# -# (light background version) - -editor -foreground: 586e75 # base01 -background: fdf6e3 # base3 -caret: 000000 - -H1 -foreground: 6c71c4 # violet -font-style: bold - -H2 -foreground: 6c71c4 # violet -font-style: bold - -H3 -foreground: 6c71c4 # violet - -H4 -foreground: 268bd2 # blue - -H5 -foreground: 268bd2 # blue - -H6 -foreground: 268bd2 # blue - -HRULE -foreground: 586e75 # base01 - -LIST_BULLET -foreground: b58900 # yellow - -LIST_ENUMERATOR -foreground: b58900 # yellow - -LINK -foreground: 2aa198 # cyan - -AUTO_LINK_URL -foreground: 2aa198 # cyan - -AUTO_LINK_EMAIL -foreground: 2aa198 # cyan - -IMAGE -foreground: d33682 # magenta - -REFERENCE -foreground: 80b58900 # yellow, reduced alpha - -CODE -foreground: 859900 # green - -EMPH -foreground: cb4b16 # orange -font-style: italic - -STRONG -foreground: dc322f # red -font-style: bold - -HTML_ENTITY -foreground: 6c71c4 # violet - -COMMENT -foreground: 93a1a1 # base1 - -VERBATIM -foreground: 859900 # green - -BLOCKQUOTE -foreground: d33682 # magenta - -STRIKE -strike-color: 586e75 # base01 - diff --git a/peg-highlight/styles/teststyle.style b/peg-highlight/styles/teststyle.style deleted file mode 100644 index 87ae7f1b..00000000 --- a/peg-highlight/styles/teststyle.style +++ /dev/null @@ -1,33 +0,0 @@ -# linecomment - -editor # comment - foreground : 13ff13 - background : 000000 # comment - -# linecomment -STRONG: - -EMPH= - # comment - foreground: 00ff00 -comment asd - background: AB0000ff - -STRONG : - dog: 1 # something - cat: 4 - font-style: underlined, Italic , BoLD #hi, hello - font-size: 14pt - font-family: Courier New, Times - -# linecomment -BOO - x: 3 - -editor-selection: - foreground: abcdef - background: abcdef - -editor-current-line: - background: ffffff - diff --git a/peg-highlight/styles/winlineseparator.style b/peg-highlight/styles/winlineseparator.style deleted file mode 100644 index adb421ae..00000000 --- a/peg-highlight/styles/winlineseparator.style +++ /dev/null @@ -1,33 +0,0 @@ -# linecomment - -editor # comment - foreground : 13ff13 - background : 000000 # comment - -# linecomment -STRONG: - -EMPH= - # comment - foreground: 00ff00 -comment asd - background: AB0000ff - -STRONG : - dog: 1 # something - cat: 4 - font-style: underlined, Italic , BoLD #hi, hello - font-size: 14pt - font-family: Courier New, Times - -# linecomment -BOO - x: 3 - -editor-selection: - foreground: abcdef - background: abcdef - -editor-current-line: - background: ffffff - diff --git a/peg-highlight/stylesheet_syntax.md b/peg-highlight/stylesheet_syntax.md deleted file mode 100644 index 687e91ed..00000000 --- a/peg-highlight/stylesheet_syntax.md +++ /dev/null @@ -1,199 +0,0 @@ - -The Syntax of PEG Markdown Highlight Stylesheets -================================================ - -[PEG Markdown Highlight][pmh] includes a parser for stylesheets that define how different Markdown language elements are to be highlighted. This document describes the syntax of these stylesheets. - -[pmh]: http://hasseg.org/peg-markdown-highlight/ - - -Example -------- - -Here is a quick, simple example of a stylesheet: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# The first comment lines
# describe the stylesheet.
 
Style rule →editor:
  foreground: ff0000 # red text← Comment
Attribute name →  font-family: Consolas← Attribute value
 
EMPH:
  font-size: 14
  font-style: bold, underlined
- - -Style Rules ------------ - -A stylesheet is composed of one or more *rules*. Rules are separated from each other by **empty lines** like so: - - H2: - foreground: ff0000 - - H3: - foreground: 00ff00 - -Each begins with the ***name* of the rule**, which is always on its own line, and may be one of the following: - -- **`editor`**: Styles that apply to the whole document/editor -- **`editor-current-line`**: Styles that apply to the current line in the editor (i.e. the line where the caret is) -- **`editor-selection`**: Styles that apply to the selected range in the editor when the user makes a selection in the text -- A Markdown element type (like `EMPH`, `REFERENCE` or `H1`): Styles that apply to occurrences of that particular element. The supported element types are: - - **`LINK`:** Explicit link (like `[click here][ref]`) - - **`AUTO_LINK_URL`:** Implicit URL link (like ``) - - **`AUTO_LINK_EMAIL`:** Implicit email link (like ``) - - **`IMAGE`:** Image definition - - **`REFERENCE`:** Reference (like `[id]: http://www.google.com`) - - **`CODE`:** Inline code - - **`EMPH`:** Emphasized text - - **`STRONG`:** Strong text - - **`LIST_BULLET`:** Bullet for an unordered list item - - **`LIST_ENUMERATOR`:** Enumerator for an ordered list item - - **`H1`:** Header, level 1 - - **`H2`:** Header, level 2 - - **`H3`:** Header, level 3 - - **`H4`:** Header, level 4 - - **`H5`:** Header, level 5 - - **`H6`:** Header, level 6 - - **`BLOCKQUOTE`:** Blockquote marker - - **`VERBATIM`:** Block of code - - **`HRULE`:** Horizontal rule - - **`HTML`:** HTML tag - - **`HTML_ENTITY`:** HTML special entity definition (like `…`) - - **`HTMLBLOCK`:** Block of HTML - - **`COMMENT`:** (HTML) Comment - - **`NOTE`:** Note - - **`STRIKE`:** Strike-through - -The name may be optionally followed by an assignment operator (either `:` or `=`): - - H1: - foreground: ff00ff - - H2 = - foreground: ff0000 - - H3 - foreground: 00ff00 - -The **order of style rules is significant**; it defines the order in which different language elements should be highlighted. *(Of course applications that use PEG Markdown Highlight and the style parser may disregard this and highlight elements in whatever order they desire.)* - -After the name of the rule, there can be one or more *attributes*. - - -Style Attributes ----------------- - -Attribute assignments are each on their own line, and they consist of the *name* of the attribute as well as the *value* assigned to it. An assignment operator (either `:` or `=`) separates the name from the value: - - attribute-name: value - attribute-name= value - -Attribute assignment lines **may be indented**. - -### Attribute Names and Types - -The following is a list of the names of predefined attributes, and the values they may be assigned: - -- `foreground-color` *(aliases: `foreground` and `color`)* - - See the *Color Attribute Values* subsection for information about valid values for this attribute. -- `background-color` *(alias: `background`)* - - See the *Color Attribute Values* subsection for information about valid values for this attribute. -- `caret-color` *(alias: `caret`)* - - See the *Color Attribute Values* subsection for information about valid values for this attribute. -- `strike-color` *(alias: `strike`)* - - See the *Color Attribute Values* subsection for information about valid values for this attribute. -- `font-size` - - An integer value for the font size, *in points* (i.e. not in pixels). The number may have a textual suffix such as `pt`. - - If the value begins with `+` or `-`, it is considered *relative* to some base font size (as defined by the host application). For example, the value `3` defines the font size as 3 (absolute) while `+3` defines it as +3 (relative), i.e. 3 point sizes larger than the base font size. -- `font-family` - - A comma-separated list of one or more arbitrary font family names. *(It is up to the application that uses the PEG Markdown Highlight library to resolve this string to actual fonts on the system.)* -- `font-style` - - A comma-separated list of one or more of the following: - - `italic` - - `bold` - - `underlined` - -Applications may also include support for any **custom attribute names and values** they desire — attributes other than the ones listed above will be included in the style parser results, with their values stored as strings. - - -## Color Attribute Values - -Colors can be specified either in **RGB** (red, green, blue) or **ARGB** (alpha, red, green, blue) formats. In both, each component is a two-character hexadecimal value (from `00` to `FF`): - - foreground: ff00ee # red = ff, green = 00, blue = ee (and implicitly, alpha = ff) - background: 99ff00ee # alpha = 99, red = ff, green = 00, blue = ee - - -Comments --------- - -Each line in a stylesheet may have a comment. The `#` character begins a line comment that continues until the end of the line: - - # this line has only this comment - H1: # this line has a style rule name and then a comment - foreground: ff0000 # this line has an attribute and then a comment - - - - - - - - - diff --git a/screenshots/_1513485266_1616037517.png b/screenshots/_1513485266_1616037517.png deleted file mode 100644 index 68a6a195..00000000 Binary files a/screenshots/_1513485266_1616037517.png and /dev/null differ diff --git a/screenshots/_1513485753_394180887.png b/screenshots/_1513485753_394180887.png deleted file mode 100644 index 158fbafc..00000000 Binary files a/screenshots/_1513485753_394180887.png and /dev/null differ diff --git a/screenshots/_1513485934_140085443.png b/screenshots/_1513485934_140085443.png deleted file mode 100644 index 5fd3eb25..00000000 Binary files a/screenshots/_1513485934_140085443.png and /dev/null differ diff --git a/screenshots/_vnote_1513485003_1746530034.png b/screenshots/_vnote_1513485003_1746530034.png deleted file mode 100644 index d0882d7c..00000000 Binary files a/screenshots/_vnote_1513485003_1746530034.png and /dev/null differ diff --git a/screenshots/qq_group.png b/screenshots/qq_group.png deleted file mode 100644 index e492543c..00000000 Binary files a/screenshots/qq_group.png and /dev/null differ diff --git a/screenshots/vnote.png b/screenshots/vnote.png deleted file mode 100644 index 69fee17d..00000000 Binary files a/screenshots/vnote.png and /dev/null differ diff --git a/screenshots/vnote_md.jpg b/screenshots/vnote_md.jpg deleted file mode 100644 index 8b4a42d6..00000000 Binary files a/screenshots/vnote_md.jpg and /dev/null differ diff --git a/src/dialog/vconfirmdeletiondialog.cpp b/src/dialog/vconfirmdeletiondialog.cpp deleted file mode 100644 index e4181bdf..00000000 --- a/src/dialog/vconfirmdeletiondialog.cpp +++ /dev/null @@ -1,248 +0,0 @@ -#include "vconfirmdeletiondialog.h" - -#include - -#include "utils/vutils.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -ConfirmItemWidget::ConfirmItemWidget(bool p_checked, - const QString &p_file, - const QString &p_tip, - int p_index, - QWidget *p_parent) - : QWidget(p_parent), m_index(p_index) -{ - setupUI(); - - m_checkBox->setChecked(p_checked); - m_fileLabel->setText(p_file); - if (!p_tip.isEmpty()) { - m_fileLabel->setToolTip(p_tip); - } -} - -void ConfirmItemWidget::setupUI() -{ - m_checkBox = new QCheckBox; - connect(m_checkBox, &QCheckBox::stateChanged, - this, &ConfirmItemWidget::checkStateChanged); - - m_fileLabel = new QLabel; - QHBoxLayout *mainLayout = new QHBoxLayout; - mainLayout->addWidget(m_checkBox); - mainLayout->addWidget(m_fileLabel); - mainLayout->addStretch(); - mainLayout->setContentsMargins(3, 0, 0, 0); - - setLayout(mainLayout); -} - -bool ConfirmItemWidget::isChecked() const -{ - return m_checkBox->isChecked(); -} - -int ConfirmItemWidget::getIndex() const -{ - return m_index; -} - -VConfirmDeletionDialog::VConfirmDeletionDialog(const QString &p_title, - const QString &p_text, - const QString &p_info, - const QVector &p_items, - bool p_enableAskAgain, - bool p_askAgainEnabled, - bool p_enablePreview, - QWidget *p_parent) - : QDialog(p_parent), - m_enableAskAgain(p_enableAskAgain), - m_askAgainEnabled(p_askAgainEnabled), - m_enablePreview(p_enablePreview), - m_items(p_items) -{ - setupUI(p_title, p_text, p_info); - - initItems(); - - updateCountLabel(); -} - -void VConfirmDeletionDialog::setupUI(const QString &p_title, - const QString &p_text, - const QString &p_info) -{ - QLabel *textLabel = NULL; - if (!p_text.isEmpty()) { - textLabel = new QLabel(p_text); - textLabel->setWordWrap(true); - } - - QLabel *infoLabel = NULL; - if (!p_info.isEmpty()) { - infoLabel = new QLabel(p_info); - infoLabel->setWordWrap(true); - } - - m_countLabel = new QLabel("Items"); - QHBoxLayout *labelLayout = new QHBoxLayout; - labelLayout->addWidget(m_countLabel); - labelLayout->addStretch(); - labelLayout->setContentsMargins(0, 0, 0, 0); - - m_listWidget = new QListWidget(); - m_listWidget->setAttribute(Qt::WA_MacShowFocusRect, false); - connect(m_listWidget, &QListWidget::currentRowChanged, - this, &VConfirmDeletionDialog::currentFileChanged); - connect(m_listWidget, &QListWidget::itemActivated, - this, [this](QListWidgetItem *p_item) { - // Open it using resource manager. - if (!p_item) { - return; - } - - ConfirmItemWidget *widget = getItemWidget(p_item); - Q_ASSERT(widget); - QString filePath = m_items[widget->getIndex()].m_path; - - if (!filePath.isEmpty()) { - QUrl url = QUrl::fromLocalFile(filePath); - QDesktopServices::openUrl(url); - } - }); - - m_previewer = new QLabel(); - - m_askAgainCB = new QCheckBox(tr("Do not ask for confirmation again")); - m_askAgainCB->setChecked(!m_askAgainEnabled); - m_askAgainCB->setVisible(m_enableAskAgain); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - m_btnBox->button(QDialogButtonBox::Ok)->setProperty("DangerBtn", true); - - QHBoxLayout *midLayout = new QHBoxLayout; - midLayout->addWidget(m_listWidget); - if (m_enablePreview) { - midLayout->addStretch(); - midLayout->addWidget(m_previewer); - midLayout->addStretch(); - } else { - midLayout->addWidget(m_previewer); - m_previewer->setVisible(false); - } - - QVBoxLayout *mainLayout = new QVBoxLayout; - if (textLabel) { - mainLayout->addWidget(textLabel); - } - - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - - mainLayout->addWidget(m_askAgainCB); - mainLayout->addWidget(m_btnBox); - mainLayout->addLayout(labelLayout); - mainLayout->addLayout(midLayout); - - setLayout(mainLayout); - setWindowTitle(p_title); -} - -QVector VConfirmDeletionDialog::getConfirmedItems() const -{ - QVector confirmedItems; - - for (int i = 0; i < m_listWidget->count(); ++i) { - ConfirmItemWidget *widget = getItemWidget(m_listWidget->item(i)); - if (widget->isChecked()) { - confirmedItems.push_back(m_items[widget->getIndex()]); - } - } - - return confirmedItems; -} - -void VConfirmDeletionDialog::initItems() -{ - m_listWidget->clear(); - - for (int i = 0; i < m_items.size(); ++i) { - ConfirmItemWidget *itemWidget = new ConfirmItemWidget(true, - m_items[i].m_name, - m_items[i].m_tip, - i, - this); - connect(itemWidget, &ConfirmItemWidget::checkStateChanged, - this, &VConfirmDeletionDialog::updateCountLabel); - - QListWidgetItem *item = new QListWidgetItem(); - QSize size = itemWidget->sizeHint(); - size.setHeight(size.height() * 2); - item->setSizeHint(size); - - m_listWidget->addItem(item); - m_listWidget->setItemWidget(item, itemWidget); - } - - m_listWidget->setMinimumSize(m_listWidget->sizeHint()); - m_listWidget->setCurrentRow(-1); - m_listWidget->setCurrentRow(0); -} - -bool VConfirmDeletionDialog::getAskAgainEnabled() const -{ - return !m_askAgainCB->isChecked(); -} - -void VConfirmDeletionDialog::currentFileChanged(int p_row) -{ - bool succeed = false; - if (p_row > -1 && m_enablePreview) { - ConfirmItemWidget *widget = getItemWidget(m_listWidget->item(p_row)); - if (widget) { - int idx = widget->getIndex(); - Q_ASSERT(idx < m_items.size()); - QPixmap image(m_items[idx].m_path); - if (!image.isNull()) { - int width = 512 * VUtils::calculateScaleFactor(); - QSize previewSize(width, width); - if (image.width() > width || image.height() > width) { - m_previewer->setPixmap(image.scaled(previewSize, Qt::KeepAspectRatio)); - } else { - m_previewer->setPixmap(image); - } - - succeed = true; - } - } - } - - m_previewer->setVisible(succeed); -} - -ConfirmItemWidget *VConfirmDeletionDialog::getItemWidget(QListWidgetItem *p_item) const -{ - QWidget *wid = m_listWidget->itemWidget(p_item); - return dynamic_cast(wid); -} - -void VConfirmDeletionDialog::updateCountLabel() -{ - int total = m_listWidget->count(); - int checked = 0; - - for (int i = 0; i < total; ++i) { - ConfirmItemWidget *widget = getItemWidget(m_listWidget->item(i)); - if (widget->isChecked()) { - ++checked; - } - } - - m_countLabel->setText(tr("%1/%2 Items").arg(checked).arg(total)); -} diff --git a/src/dialog/vconfirmdeletiondialog.h b/src/dialog/vconfirmdeletiondialog.h deleted file mode 100644 index d67d74b4..00000000 --- a/src/dialog/vconfirmdeletiondialog.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef VCONFIRMDELETIONDIALOG_H -#define VCONFIRMDELETIONDIALOG_H - -#include -#include - -class QLabel; -class QPushButton; -class QDialogButtonBox; -class QListWidget; -class QListWidgetItem; -class ConfirmItemWidget; -class QCheckBox; - -// Information about a deletion item needed to confirm. -struct ConfirmItemInfo -{ - ConfirmItemInfo() - : m_data(NULL) - { - } - - ConfirmItemInfo(const QString &p_name, - const QString &p_tip, - const QString &p_path, - void *p_data) - : m_name(p_name), m_tip(p_tip), m_path(p_path), m_data(p_data) - { - } - - QString m_name; - QString m_tip; - QString m_path; - void *m_data; -}; - -class ConfirmItemWidget : public QWidget -{ - Q_OBJECT -public: - ConfirmItemWidget(bool p_checked, - const QString &p_file, - const QString &p_tip, - int p_index, - QWidget *p_parent = NULL); - - bool isChecked() const; - - int getIndex() const; - -signals: - // Emit when item's check state changed. - void checkStateChanged(int p_state); - -private: - void setupUI(); - - QCheckBox *m_checkBox; - QLabel *m_fileLabel; - - int m_index; -}; - -class VConfirmDeletionDialog : public QDialog -{ - Q_OBJECT -public: - VConfirmDeletionDialog(const QString &p_title, - const QString &p_text, - const QString &p_info, - const QVector &p_items, - bool p_enableAskAgain, - bool p_askAgainEnabled, - bool p_enablePreview, - QWidget *p_parent = 0); - - QVector getConfirmedItems() const; - - bool getAskAgainEnabled() const; - -private slots: - void currentFileChanged(int p_row); - - void updateCountLabel(); - -private: - void setupUI(const QString &p_title, - const QString &p_text, - const QString &p_info); - - void initItems(); - - ConfirmItemWidget *getItemWidget(QListWidgetItem *p_item) const; - - QLabel *m_countLabel; - QListWidget *m_listWidget; - QLabel *m_previewer; - QDialogButtonBox *m_btnBox; - QCheckBox *m_askAgainCB; - - bool m_enableAskAgain; - // Init value if m_enableAskAgain is true. - bool m_askAgainEnabled; - - bool m_enablePreview; - - QVector m_items; -}; - -#endif // VCONFIRMDELETIONDIALOG_H diff --git a/src/dialog/vdeletenotebookdialog.cpp b/src/dialog/vdeletenotebookdialog.cpp deleted file mode 100644 index ffab9fce..00000000 --- a/src/dialog/vdeletenotebookdialog.cpp +++ /dev/null @@ -1,125 +0,0 @@ -#include -#include "vdeletenotebookdialog.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -VDeleteNotebookDialog::VDeleteNotebookDialog(const QString &p_title, - const VNotebook *p_notebook, - QWidget *p_parent) - : QDialog(p_parent), m_notebook(p_notebook) -{ - setupUI(p_title, m_notebook->getName()); -} - -void VDeleteNotebookDialog::setupUI(const QString &p_title, const QString &p_name) -{ - QLabel *infoLabel = new QLabel(tr("Are you sure to delete notebook %2?") - .arg(g_config->c_dataTextStyle).arg(p_name)); - m_warningLabel = new QLabel(); - m_warningLabel->setWordWrap(true); - - m_deleteCheck = new QCheckBox(tr("Delete files from disk"), this); - m_deleteCheck->setChecked(false); - m_deleteCheck->setToolTip(tr("When checked, VNote will delete all files (including Recycle Bin) of this notebook from disk")); - connect(m_deleteCheck, &QCheckBox::stateChanged, - this, &VDeleteNotebookDialog::deleteCheckChanged); - - deleteCheckChanged(false); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("DangerBtn", true); - - // Standard Warning icon. - QLabel *iconLabel = new QLabel(); - QPixmap pixmap = standardIcon(QMessageBox::Warning); - if (pixmap.isNull()) { - iconLabel->hide(); - } else { - iconLabel->setPixmap(pixmap); - } - - QVBoxLayout *iconLayout = new QVBoxLayout(); - iconLayout->addStretch(); - iconLayout->addWidget(iconLabel); - iconLayout->addStretch(); - - QVBoxLayout *infoLayout = new QVBoxLayout(); - infoLayout->addWidget(infoLabel); - infoLayout->addWidget(m_deleteCheck); - infoLayout->addWidget(m_warningLabel); - - QHBoxLayout *topLayout = new QHBoxLayout(); - topLayout->addLayout(iconLayout); - topLayout->addLayout(infoLayout); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_btnBox); - - setLayout(mainLayout); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setWindowTitle(p_title); -} - -bool VDeleteNotebookDialog::getDeleteFiles() const -{ - return m_deleteCheck->isChecked(); -} - -QPixmap VDeleteNotebookDialog::standardIcon(QMessageBox::Icon p_icon) -{ - QStyle *style = this->style(); - int iconSize = style->pixelMetric(QStyle::PM_MessageBoxIconSize, 0, this); - QIcon tmpIcon; - switch (p_icon) { - case QMessageBox::Information: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxInformation, 0, this); - break; - case QMessageBox::Warning: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxWarning, 0, this); - break; - case QMessageBox::Critical: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxCritical, 0, this); - break; - case QMessageBox::Question: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxQuestion, 0, this); - break; - default: - break; - } - - if (!tmpIcon.isNull()) { - QWindow *window = this->windowHandle(); - if (!window) { - if (const QWidget *nativeParent = this->nativeParentWidget()) { - window = nativeParent->windowHandle(); - } - } - return tmpIcon.pixmap(window, QSize(iconSize, iconSize)); - } - return QPixmap(); -} - -void VDeleteNotebookDialog::deleteCheckChanged(int p_state) -{ - if (!p_state) { - m_warningLabel->setText(tr("VNote won't delete files in directory %2.") - .arg(g_config->c_dataTextStyle).arg(m_notebook->getPath())); - } else { - m_warningLabel->setText(tr("WARNING: " - "VNote may delete ANY files in directory %3 " - "and directory %4!
" - "VNote will try to delete all the root folders within this notebook one by one.
" - "It may be UNRECOVERABLE!") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(m_notebook->getPath()) - .arg(m_notebook->getRecycleBinFolderPath())); - } -} diff --git a/src/dialog/vdeletenotebookdialog.h b/src/dialog/vdeletenotebookdialog.h deleted file mode 100644 index d88baac8..00000000 --- a/src/dialog/vdeletenotebookdialog.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef VDELETENOTEBOOKDIALOG_H -#define VDELETENOTEBOOKDIALOG_H - -#include -#include - -class QLabel; -class QLineEdit; -class QString; -class QCheckBox; -class QDialogButtonBox; -class VNotebook; - -class VDeleteNotebookDialog : public QDialog -{ - Q_OBJECT -public: - VDeleteNotebookDialog(const QString &p_title, - const VNotebook *p_notebook, - QWidget *p_parent = 0); - - // Whether delete files from disk. - bool getDeleteFiles() const; - -private slots: - void deleteCheckChanged(int p_state); - -private: - void setupUI(const QString &p_title, const QString &p_name); - QPixmap standardIcon(QMessageBox::Icon p_icon); - - const VNotebook *m_notebook; - QLabel *m_warningLabel; - QCheckBox *m_deleteCheck; - QDialogButtonBox *m_btnBox; -}; - -#endif // VDELETENOTEBOOKDIALOG_H diff --git a/src/dialog/vdirinfodialog.cpp b/src/dialog/vdirinfodialog.cpp deleted file mode 100644 index 50c9e3eb..00000000 --- a/src/dialog/vdirinfodialog.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include "vdirinfodialog.h" -#include "vdirectory.h" -#include "vconfigmanager.h" -#include "vlineedit.h" -#include "utils/vutils.h" - -extern VConfigManager *g_config; - -VDirInfoDialog::VDirInfoDialog(const QString &title, - const QString &info, - const VDirectory *directory, - VDirectory *parentDirectory, - QWidget *parent) - : QDialog(parent), title(title), info(info), - m_directory(directory), m_parentDirectory(parentDirectory) -{ - setupUI(); - - connect(m_nameEdit, &QLineEdit::textChanged, this, &VDirInfoDialog::handleInputChanged); - - handleInputChanged(); -} - -void VDirInfoDialog::setupUI() -{ - QLabel *infoLabel = NULL; - if (!info.isEmpty()) { - infoLabel = new QLabel(info); - } - - m_nameEdit = new VLineEdit(m_directory->getName()); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_nameEdit); - m_nameEdit->setValidator(validator); - m_nameEdit->selectAll(); - - // Created time. - QString createdTimeStr = VUtils::displayDateTime(m_directory->getCreatedTimeUtc().toLocalTime()); - QLabel *createdTimeLabel = new QLabel(createdTimeStr); - - QFormLayout *topLayout = new QFormLayout(); - topLayout->addRow(tr("Folder &name:"), m_nameEdit); - topLayout->addRow(tr("Created time:"), createdTimeLabel); - - m_warnLabel = new QLabel(); - m_warnLabel->setWordWrap(true); - m_warnLabel->hide(); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - m_nameEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_warnLabel); - mainLayout->addWidget(m_btnBox); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setLayout(mainLayout); - - setWindowTitle(title); -} - -void VDirInfoDialog::handleInputChanged() -{ - bool showWarnLabel = false; - QString name = m_nameEdit->getEvaluatedText(); - bool nameOk = !name.isEmpty(); - if (nameOk && name != m_directory->getName()) { - // Check if the name conflicts with existing directory name. - // Case-insensitive when creating note. - const VDirectory *directory = m_parentDirectory->findSubDirectory(name, false); - QString warnText; - if (directory && directory != m_directory) { - nameOk = false; - warnText = tr("WARNING: " - "Name (case-insensitive) %3 already exists. " - "Please choose another name.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } else if (!VUtils::checkFileNameLegal(name)) { - // Check if evaluated name contains illegal characters. - nameOk = false; - warnText = tr("WARNING: " - "Name %3 contains illegal characters " - "(after magic word evaluation).") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } - - if (!nameOk) { - showWarnLabel = true; - m_warnLabel->setText(warnText); - } - } - - m_warnLabel->setVisible(showWarnLabel); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(nameOk); -} - -QString VDirInfoDialog::getNameInput() const -{ - return m_nameEdit->getEvaluatedText(); -} diff --git a/src/dialog/vdirinfodialog.h b/src/dialog/vdirinfodialog.h deleted file mode 100644 index d23a0211..00000000 --- a/src/dialog/vdirinfodialog.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef VDIRINFODIALOG_H -#define VDIRINFODIALOG_H - -#include - -class QLabel; -class VLineEdit; -class QDialogButtonBox; -class QString; -class VDirectory; - -class VDirInfoDialog : public QDialog -{ - Q_OBJECT -public: - VDirInfoDialog(const QString &title, - const QString &info, - const VDirectory *directory, - VDirectory *parentDirectory, - QWidget *parent = 0); - - QString getNameInput() const; - -private slots: - void handleInputChanged(); - -private: - void setupUI(); - - VLineEdit *m_nameEdit; - QLabel *m_warnLabel; - QDialogButtonBox *m_btnBox; - - QString title; - QString info; - - const VDirectory *m_directory; - VDirectory *m_parentDirectory; -}; -#endif // VDIRINFODIALOG_H diff --git a/src/dialog/veditsnippetdialog.cpp b/src/dialog/veditsnippetdialog.cpp deleted file mode 100644 index 3845cf83..00000000 --- a/src/dialog/veditsnippetdialog.cpp +++ /dev/null @@ -1,309 +0,0 @@ -#include "veditsnippetdialog.h" -#include - -#include "utils/vutils.h" -#include "vlineedit.h" -#include "vconfigmanager.h" -#include "utils/vmetawordmanager.h" - -extern VMetaWordManager *g_mwMgr; - -extern VConfigManager *g_config; - -VEditSnippetDialog::VEditSnippetDialog(const QString &p_title, - const QString &p_info, - const QVector &p_snippets, - const VSnippet &p_snippet, - QWidget *p_parent) - : QDialog(p_parent), - m_snippets(p_snippets), - m_snippet(p_snippet) -{ - setupUI(p_title, p_info); - - handleInputChanged(); -} - -void VEditSnippetDialog::setupUI(const QString &p_title, const QString &p_info) -{ - QLabel *infoLabel = NULL; - if (!p_info.isEmpty()) { - infoLabel = new QLabel(p_info); - infoLabel->setWordWrap(true); - } - - // Name. - m_nameEdit = new VLineEdit(m_snippet.getName()); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_nameEdit); - m_nameEdit->setValidator(validator); - - // Type. - m_typeCB = VUtils::getComboBox(); - for (int i = 0; i < VSnippet::Type::Invalid; ++i) { - m_typeCB->addItem(VSnippet::typeStr(static_cast(i)), i); - } - - int typeIdx = m_typeCB->findData((int)m_snippet.getType()); - Q_ASSERT(typeIdx > -1); - m_typeCB->setCurrentIndex(typeIdx); - - // Shortcut. - m_shortcutCB = VUtils::getComboBox(); - m_shortcutCB->addItem(tr("None"), QChar()); - auto shortcuts = getAvailableShortcuts(); - for (auto it : shortcuts) { - m_shortcutCB->addItem(it, it); - } - - QChar sh = m_snippet.getShortcut(); - if (sh.isNull()) { - m_shortcutCB->setCurrentIndex(0); - } else { - int shortcutIdx = m_shortcutCB->findData(sh); - m_shortcutCB->setCurrentIndex(shortcutIdx < 0 ? 0 : shortcutIdx); - } - - // Cursor mark. - m_cursorMarkEdit = new QLineEdit(m_snippet.getCursorMark()); - m_cursorMarkEdit->setToolTip(tr("String in the content to mark the cursor position")); - - // Selection mark. - m_selectionMarkEdit = new QLineEdit(m_snippet.getSelectionMark()); - m_selectionMarkEdit->setToolTip(tr("String in the content to be replaced with selected text")); - - // Auto Indent. - m_autoIndentCB = new QCheckBox(tr("Auto indent"), this); - m_autoIndentCB->setToolTip(tr("Auto indent the content according to the first line")); - m_autoIndentCB->setChecked(m_snippet.getAutoIndent()); - - // Content. - m_contentEdit = new QTextEdit(); - m_contentEdit->setProperty("LineEdit", true); - setContentEditByType(); - - QFormLayout *topLayout = new QFormLayout(); - topLayout->addRow(tr("Snippet &name:"), m_nameEdit); - topLayout->addRow(tr("Snippet &type:"), m_typeCB); - topLayout->addRow(tr("Shortc&ut:"), m_shortcutCB); - topLayout->addRow(tr("Cursor &mark:"), m_cursorMarkEdit); - topLayout->addRow(tr("&Selection mark:"), m_selectionMarkEdit); - topLayout->addWidget(m_autoIndentCB); - topLayout->addRow(tr("&Content:"), m_contentEdit); - - m_warnLabel = new QLabel(); - m_warnLabel->setWordWrap(true); - m_warnLabel->hide(); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - m_nameEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_warnLabel); - mainLayout->addWidget(m_btnBox); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setLayout(mainLayout); - - setWindowTitle(p_title); - - connect(m_nameEdit, &QLineEdit::textChanged, - this, &VEditSnippetDialog::handleInputChanged); - - connect(m_typeCB, static_cast(&QComboBox::currentIndexChanged), - this, &VEditSnippetDialog::handleInputChanged); - - connect(m_cursorMarkEdit, &QLineEdit::textChanged, - this, &VEditSnippetDialog::handleInputChanged); - - connect(m_selectionMarkEdit, &QLineEdit::textChanged, - this, &VEditSnippetDialog::handleInputChanged); - - connect(m_contentEdit, &QTextEdit::textChanged, - this, &VEditSnippetDialog::handleInputChanged); -} - -void VEditSnippetDialog::handleInputChanged() -{ - bool showWarnLabel = false; - QString name = m_nameEdit->getEvaluatedText(); - bool nameOk = !name.isEmpty(); - if (nameOk && name != m_snippet.getName()) { - // Check if the name conflicts with existing snippet name. - // Case-insensitive. - QString lowerName = name.toLower(); - bool conflicted = false; - for (auto const & item : m_snippets) { - if (item.getName() == name) { - conflicted = true; - break; - } - } - - QString warnText; - if (conflicted) { - nameOk = false; - warnText = tr("WARNING: " - "Name (case-insensitive) %3 already exists. " - "Please choose another name.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } else if (!VUtils::checkFileNameLegal(name)) { - // Check if evaluated name contains illegal characters. - nameOk = false; - warnText = tr("WARNING: " - "Name %3 contains illegal characters " - "(after magic word evaluation).") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } - - if (!nameOk) { - showWarnLabel = true; - m_warnLabel->setText(warnText); - } - } - - QString cursorMark = m_cursorMarkEdit->text(); - bool cursorMarkOk = true; - if (nameOk && !cursorMark.isEmpty()) { - // Check if the mark appears more than once in the content. - QString selectionMark = m_selectionMarkEdit->text(); - QString content = getContentEditByType(); - content = g_mwMgr->evaluate(content); - QString warnText; - if (content.count(cursorMark) > 1) { - cursorMarkOk = false; - warnText = tr("WARNING: " - "Cursor mark %3 occurs more than once " - "in the content (after magic word evaluation). " - "Please choose another mark.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(cursorMark); - } else if ((cursorMark == selectionMark - || cursorMark.contains(selectionMark) - || selectionMark.contains(cursorMark)) - && !selectionMark.isEmpty()) { - cursorMarkOk = false; - warnText = tr("WARNING: " - "Cursor mark %3 conflicts with selection mark. " - "Please choose another mark.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(cursorMark); - } - - if (!cursorMarkOk) { - showWarnLabel = true; - m_warnLabel->setText(warnText); - } - } - - m_warnLabel->setVisible(showWarnLabel); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(nameOk && cursorMarkOk); -} - -void VEditSnippetDialog::setContentEditByType() -{ - switch (m_snippet.getType()) { - case VSnippet::Type::PlainText: - m_contentEdit->setPlainText(m_snippet.getContent()); - break; - - case VSnippet::Type::Html: - m_contentEdit->setHtml(m_snippet.getContent()); - break; - - default: - m_contentEdit->setPlainText(m_snippet.getContent()); - break; - } -} - -QString VEditSnippetDialog::getContentEditByType() const -{ - if (m_typeCB->currentIndex() == -1) { - return QString(); - } - - switch (static_cast(m_typeCB->currentData().toInt())) { - case VSnippet::Type::PlainText: - return m_contentEdit->toPlainText(); - - case VSnippet::Type::Html: - return m_contentEdit->toHtml(); - - default: - return m_contentEdit->toPlainText(); - } -} - -QString VEditSnippetDialog::getNameInput() const -{ - return m_nameEdit->getEvaluatedText(); -} - -VSnippet::Type VEditSnippetDialog::getTypeInput() const -{ - return static_cast(m_typeCB->currentData().toInt()); -} - -QString VEditSnippetDialog::getCursorMarkInput() const -{ - return m_cursorMarkEdit->text(); -} - -QString VEditSnippetDialog::getSelectionMarkInput() const -{ - return m_selectionMarkEdit->text(); -} - -QString VEditSnippetDialog::getContentInput() const -{ - return getContentEditByType(); -} - -QChar VEditSnippetDialog::getShortcutInput() const -{ - return m_shortcutCB->currentData().toChar(); -} - -bool VEditSnippetDialog::getAutoIndentInput() const -{ - return m_autoIndentCB->isChecked(); -} - -QVector VEditSnippetDialog::getAvailableShortcuts() const -{ - QVector ret = VSnippet::getAllShortcuts(); - - QChar curCh = m_snippet.getShortcut(); - // Remove those have already been assigned to snippets. - for (auto const & snip : m_snippets) { - QChar ch = snip.getShortcut(); - if (ch.isNull()) { - continue; - } - - if (ch != curCh) { - ret.removeOne(ch); - } - } - - return ret; -} diff --git a/src/dialog/veditsnippetdialog.h b/src/dialog/veditsnippetdialog.h deleted file mode 100644 index 8c4987b4..00000000 --- a/src/dialog/veditsnippetdialog.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef VEDITSNIPPETDIALOG_H -#define VEDITSNIPPETDIALOG_H - -#include -#include - -#include "vsnippet.h" - -class VLineEdit; -class QLineEdit; -class QLabel; -class QDialogButtonBox; -class QComboBox; -class QTextEdit; -class QCheckBox; - - -class VEditSnippetDialog : public QDialog -{ - Q_OBJECT -public: - VEditSnippetDialog(const QString &p_title, - const QString &p_info, - const QVector &p_snippets, - const VSnippet &p_snippet, - QWidget *p_parent = nullptr); - - QString getNameInput() const; - - VSnippet::Type getTypeInput() const; - - QString getCursorMarkInput() const; - - QString getSelectionMarkInput() const; - - QString getContentInput() const; - - QChar getShortcutInput() const; - - bool getAutoIndentInput() const; - -private slots: - void handleInputChanged(); - -private: - void setupUI(const QString &p_title, const QString &p_info); - - void setContentEditByType(); - - QString getContentEditByType() const; - - QVector getAvailableShortcuts() const; - - VLineEdit *m_nameEdit; - QComboBox *m_typeCB; - QComboBox *m_shortcutCB; - QLineEdit *m_cursorMarkEdit; - QLineEdit *m_selectionMarkEdit; - QCheckBox *m_autoIndentCB; - QTextEdit *m_contentEdit; - - QLabel *m_warnLabel; - QDialogButtonBox *m_btnBox; - - const QVector &m_snippets; - - const VSnippet &m_snippet; -}; - -#endif // VEDITSNIPPETDIALOG_H diff --git a/src/dialog/vfileinfodialog.cpp b/src/dialog/vfileinfodialog.cpp deleted file mode 100644 index 7af9a5f0..00000000 --- a/src/dialog/vfileinfodialog.cpp +++ /dev/null @@ -1,147 +0,0 @@ -#include -#include "vfileinfodialog.h" -#include "vdirectory.h" -#include "vnotefile.h" -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "vlineedit.h" - -extern VConfigManager *g_config; - -VFileInfoDialog::VFileInfoDialog(const QString &title, - const QString &info, - VDirectory *directory, - const VNoteFile *file, - QWidget *parent) - : QDialog(parent), m_directory(directory), m_file(file) -{ - setupUI(title, info); - - connect(m_nameEdit, &QLineEdit::textChanged, this, &VFileInfoDialog::handleInputChanged); - - handleInputChanged(); -} - -void VFileInfoDialog::setupUI(const QString &p_title, const QString &p_info) -{ - QLabel *infoLabel = NULL; - if (!p_info.isEmpty()) { - infoLabel = new QLabel(p_info); - } - - // File name. - QString name = m_file->getName(); - m_nameEdit = new VLineEdit(name); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_nameEdit); - m_nameEdit->setValidator(validator); - int baseStart = 0, baseLength = name.size(); - int dotIdx = name.lastIndexOf('.'); - if (dotIdx != -1) { - baseLength = dotIdx; - } - - // Select without suffix. - m_nameEdit->setSelection(baseStart, baseLength); - - // Attachment folder. - QLineEdit *attachmentFolderEdit = new QLineEdit(m_file->getAttachmentFolder()); - attachmentFolderEdit->setPlaceholderText(tr("Will be assigned when adding attachments")); - attachmentFolderEdit->setToolTip(tr("The folder to hold attachments of this note")); - attachmentFolderEdit->setReadOnly(true); - - // Created time. - QString createdTimeStr = VUtils::displayDateTime(m_file->getCreatedTimeUtc().toLocalTime()); - QLabel *createdTimeLabel = new QLabel(createdTimeStr); - - // Modified time. - createdTimeStr = VUtils::displayDateTime(m_file->getModifiedTimeUtc().toLocalTime()); - QLabel *modifiedTimeLabel = new QLabel(createdTimeStr); - modifiedTimeLabel->setToolTip(tr("Last modified time within VNote")); - - QFormLayout *topLayout = new QFormLayout(); - topLayout->addRow(tr("Note &name:"), m_nameEdit); - topLayout->addRow(tr("Attachment folder:"), attachmentFolderEdit); - topLayout->addRow(tr("Created time:"), createdTimeLabel); - topLayout->addRow(tr("Modified time:"), modifiedTimeLabel); - - m_warnLabel = new QLabel(); - m_warnLabel->setWordWrap(true); - m_warnLabel->hide(); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - m_nameEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_warnLabel); - mainLayout->addWidget(m_btnBox); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setLayout(mainLayout); - - setWindowTitle(p_title); -} - -void VFileInfoDialog::handleInputChanged() -{ - bool showWarnLabel = false; - QString name = m_nameEdit->getEvaluatedText(); - bool nameOk = !name.isEmpty(); - if (nameOk && name != m_file->getName()) { - // Check if the name conflicts with existing note name. - // Case-insensitive when creating note. - const VNoteFile *file = m_directory->findFile(name, false); - QString warnText; - if (file && file != m_file) { - nameOk = false; - warnText = tr("WARNING: " - "Name (case-insensitive) %3 already exists. " - "Please choose another name.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } else if (m_file->getDocType() != DocType::Unknown - && VUtils::docTypeFromName(name) != m_file->getDocType()) { - // Check if the name change the doc type. - nameOk = false; - warnText = tr("WARNING: " - "Changing type of the note is not supported. " - "Please use the same suffix as the old one.") - .arg(g_config->c_warningTextStyle); - } else if (!VUtils::checkFileNameLegal(name)) { - // Check if evaluated name contains illegal characters. - nameOk = false; - warnText = tr("WARNING: " - "Name %3 contains illegal characters " - "(after magic word evaluation).") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } - - if (!nameOk) { - showWarnLabel = true; - m_warnLabel->setText(warnText); - } - } - - m_warnLabel->setVisible(showWarnLabel); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(nameOk); -} - -QString VFileInfoDialog::getNameInput() const -{ - return m_nameEdit->getEvaluatedText(); -} diff --git a/src/dialog/vfileinfodialog.h b/src/dialog/vfileinfodialog.h deleted file mode 100644 index 015705f0..00000000 --- a/src/dialog/vfileinfodialog.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef VFILEINFODIALOG_H -#define VFILEINFODIALOG_H - -#include - -class QLabel; -class VLineEdit; -class QDialogButtonBox; -class QString; -class VDirectory; -class VNoteFile; - -// File information dialog for internal note file. -class VFileInfoDialog : public QDialog -{ - Q_OBJECT -public: - VFileInfoDialog(const QString &title, - const QString &info, - VDirectory *directory, - const VNoteFile *file, - QWidget *parent = 0); - - QString getNameInput() const; - -private slots: - void handleInputChanged(); - -private: - void setupUI(const QString &p_title, const QString &p_info); - - VLineEdit *m_nameEdit; - QLabel *m_warnLabel; - QDialogButtonBox *m_btnBox; - - VDirectory *m_directory; - const VNoteFile *m_file; -}; - -#endif // VFILEINFODIALOG_H diff --git a/src/dialog/vfindreplacedialog.cpp b/src/dialog/vfindreplacedialog.cpp deleted file mode 100644 index 9dc196f1..00000000 --- a/src/dialog/vfindreplacedialog.cpp +++ /dev/null @@ -1,308 +0,0 @@ -#include "vfindreplacedialog.h" -#include - -#include "utils/viconutils.h" - -VFindReplaceDialog::VFindReplaceDialog(QWidget *p_parent) - : QWidget(p_parent), m_options(0), m_replaceAvailable(true) -{ - setupUI(); -} - -void VFindReplaceDialog::setupUI() -{ - QLabel *titleLabel = new QLabel(tr("Find/Replace")); - titleLabel->setProperty("TitleLabel", true); - m_closeBtn = new QPushButton(VIconUtils::titleIcon(":/resources/icons/close.svg"), ""); - m_closeBtn->setProperty("TitleBtn", true); - QHBoxLayout *titleLayout = new QHBoxLayout(); - titleLayout->addWidget(titleLabel); - titleLayout->addWidget(m_closeBtn); - titleLayout->setStretch(0, 1); - titleLayout->setStretch(1, 0); - titleLayout->setContentsMargins(0, 0, 0, 0); - titleLayout->setSpacing(0); - QWidget *titleWidget = new QWidget(); - titleWidget->setObjectName("FindReplaceTitleWidget"); - titleWidget->setLayout(titleLayout); - - // Find - QLabel *findLabel = new QLabel(tr("Find:")); - m_findEdit = new QLineEdit(); - m_findEdit->setPlaceholderText(tr("Enter text to search")); - findLabel->setBuddy(m_findEdit); - m_findNextBtn = new QPushButton(tr("Find &Next")); - m_findNextBtn->setProperty("FlatBtn", true); - m_findNextBtn->setDefault(true); - m_findPrevBtn = new QPushButton(tr("Find &Previous")); - m_findPrevBtn->setProperty("FlatBtn", true); - - // Replace - QLabel *replaceLabel = new QLabel(tr("&Replace with:")); - m_replaceEdit = new QLineEdit(); - m_replaceEdit->setPlaceholderText(tr("Enter text to replace with")); - replaceLabel->setBuddy(m_replaceEdit); - m_replaceBtn = new QPushButton(tr("Replace")); - m_replaceBtn->setProperty("FlatBtn", true); - m_replaceFindBtn = new QPushButton(tr("Replace && Fin&d")); - m_replaceFindBtn->setProperty("FlatBtn", true); - m_replaceAllBtn = new QPushButton(tr("Replace A&ll")); - m_replaceAllBtn->setProperty("FlatBtn", true); - m_advancedBtn = new QPushButton(tr("&Advanced >>")); - m_advancedBtn->setProperty("FlatBtn", true); - m_advancedBtn->setCheckable(true); - - // Options - m_caseSensitiveCheck = new QCheckBox(tr("&Case sensitive"), this); - connect(m_caseSensitiveCheck, &QCheckBox::stateChanged, - this, &VFindReplaceDialog::optionBoxToggled); - m_wholeWordOnlyCheck = new QCheckBox(tr("&Whole word only"), this); - connect(m_wholeWordOnlyCheck, &QCheckBox::stateChanged, - this, &VFindReplaceDialog::optionBoxToggled); - m_regularExpressionCheck = new QCheckBox(tr("Re&gular expression"), this); - connect(m_regularExpressionCheck, &QCheckBox::stateChanged, - this, &VFindReplaceDialog::optionBoxToggled); - m_incrementalSearchCheck = new QCheckBox(tr("&Incremental search"), this); - connect(m_incrementalSearchCheck, &QCheckBox::stateChanged, - this, &VFindReplaceDialog::optionBoxToggled); - - QGridLayout *gridLayout = new QGridLayout(); - gridLayout->addWidget(findLabel, 0, 0); - gridLayout->addWidget(m_findEdit, 0, 1); - gridLayout->addWidget(m_findNextBtn, 0, 2); - gridLayout->addWidget(m_findPrevBtn, 0, 3); - gridLayout->addWidget(replaceLabel, 1, 0); - gridLayout->addWidget(m_replaceEdit, 1, 1); - gridLayout->addWidget(m_replaceBtn, 1, 2); - gridLayout->addWidget(m_replaceFindBtn, 1, 3); - gridLayout->addWidget(m_replaceAllBtn, 1, 4); - gridLayout->addWidget(m_advancedBtn, 1, 5); - gridLayout->addWidget(m_caseSensitiveCheck, 2, 1); - gridLayout->addWidget(m_wholeWordOnlyCheck, 2, 2); - gridLayout->addWidget(m_regularExpressionCheck, 3, 1); - gridLayout->addWidget(m_incrementalSearchCheck, 3, 2); - gridLayout->setColumnStretch(0, 0); - gridLayout->setColumnStretch(1, 4); - gridLayout->setColumnStretch(2, 1); - gridLayout->setColumnStretch(3, 1); - gridLayout->setColumnStretch(4, 1); - gridLayout->setColumnStretch(5, 1); - gridLayout->setColumnStretch(6, 3); - - QMargins margin = gridLayout->contentsMargins(); - margin.setLeft(3); - gridLayout->setContentsMargins(margin); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(titleWidget); - mainLayout->addLayout(gridLayout); - mainLayout->setContentsMargins(0, 0, 0, 0); - - setLayout(mainLayout); - - setTabOrder(m_findEdit, m_findNextBtn); - setTabOrder(m_findNextBtn, m_findPrevBtn); - setTabOrder(m_findPrevBtn, m_replaceEdit); - setTabOrder(m_replaceEdit, m_replaceBtn); - setTabOrder(m_replaceBtn, m_replaceFindBtn); - setTabOrder(m_replaceFindBtn, m_replaceAllBtn); - setTabOrder(m_replaceAllBtn, m_advancedBtn); - setTabOrder(m_advancedBtn, m_caseSensitiveCheck); - setTabOrder(m_caseSensitiveCheck, m_wholeWordOnlyCheck); - setTabOrder(m_wholeWordOnlyCheck, m_regularExpressionCheck); - setTabOrder(m_regularExpressionCheck, m_incrementalSearchCheck); - setTabOrder(m_incrementalSearchCheck, m_closeBtn); - - m_caseSensitiveCheck->hide(); - m_wholeWordOnlyCheck->hide(); - m_regularExpressionCheck->hide(); - m_incrementalSearchCheck->hide(); - - // Signals - connect(m_closeBtn, &QPushButton::clicked, - this, &VFindReplaceDialog::closeDialog); - connect(m_findEdit, &QLineEdit::textChanged, - this, &VFindReplaceDialog::handleFindTextChanged); - connect(m_advancedBtn, &QPushButton::toggled, - this, &VFindReplaceDialog::advancedBtnToggled); - connect(m_findNextBtn, SIGNAL(clicked(bool)), - this, SLOT(findNext())); - connect(m_findPrevBtn, SIGNAL(clicked(bool)), - this, SLOT(findPrevious())); - connect(m_replaceBtn, SIGNAL(clicked(bool)), - this, SLOT(replace())); - connect(m_replaceFindBtn, SIGNAL(clicked(bool)), - this, SLOT(replaceFind())); - connect(m_replaceAllBtn, SIGNAL(clicked(bool)), - this, SLOT(replaceAll())); -} - -void VFindReplaceDialog::closeDialog() -{ - if (this->isVisible()) { - hide(); - emit dialogClosed(); - } -} - -void VFindReplaceDialog::keyPressEvent(QKeyEvent *event) -{ - switch (event->key()) { - case Qt::Key_Escape: - event->accept(); - closeDialog(); - return; - - case Qt::Key_Return: - { - int modifiers = event->modifiers(); - bool shift = false; - if (modifiers == Qt::ShiftModifier) { - shift = true; - } else if (modifiers != Qt::NoModifier) { - break; - } - if (!m_findEdit->hasFocus() && !m_replaceEdit->hasFocus()) { - break; - } - event->accept(); - if (shift) { - findPrevious(); - } else { - findNext(); - } - return; - } - - default: - break; - } - QWidget::keyPressEvent(event); -} - -void VFindReplaceDialog::openDialog(QString p_text) -{ - show(); - if (!p_text.isEmpty()) { - m_findEdit->setText(p_text); - } - m_findEdit->setFocus(); - m_findEdit->selectAll(); -} - -void VFindReplaceDialog::handleFindTextChanged(const QString &p_text) -{ - emit findTextChanged(p_text, m_options); -} - -void VFindReplaceDialog::advancedBtnToggled(bool p_checked) -{ - if (p_checked) { - m_advancedBtn->setText("B&asic <<"); - } else { - m_advancedBtn->setText("&Advanced <<"); - } - - m_caseSensitiveCheck->setVisible(p_checked); - m_wholeWordOnlyCheck->setVisible(p_checked); - m_regularExpressionCheck->setVisible(p_checked); - m_incrementalSearchCheck->setVisible(p_checked); -} - -void VFindReplaceDialog::optionBoxToggled(int p_state) -{ - QObject *obj = sender(); - FindOption opt = FindOption::CaseSensitive; - if (obj == m_caseSensitiveCheck) { - opt = FindOption::CaseSensitive; - } else if (obj == m_wholeWordOnlyCheck) { - opt = FindOption::WholeWordOnly; - } else if (obj == m_regularExpressionCheck) { - opt = FindOption::RegularExpression; - } else { - opt = FindOption::IncrementalSearch; - } - - if (p_state) { - m_options |= opt; - } else { - m_options &= ~opt; - } - emit findOptionChanged(m_options); -} - -void VFindReplaceDialog::setOption(FindOption p_opt, bool p_enabled) -{ - if (p_opt == FindOption::CaseSensitive) { - m_caseSensitiveCheck->setChecked(p_enabled); - } else if (p_opt == FindOption::WholeWordOnly) { - m_wholeWordOnlyCheck->setChecked(p_enabled); - } else if (p_opt == FindOption::RegularExpression) { - m_regularExpressionCheck->setChecked(p_enabled); - } else if (p_opt == FindOption::IncrementalSearch) { - m_incrementalSearchCheck->setChecked(p_enabled); - } else { - Q_ASSERT(false); - } -} - -void VFindReplaceDialog::findNext() -{ - QString text = m_findEdit->text(); - if (text.isEmpty()) { - return; - } - emit findNext(text, m_options, true); -} - -void VFindReplaceDialog::findPrevious() -{ - QString text = m_findEdit->text(); - if (text.isEmpty()) { - return; - } - emit findNext(text, m_options, false); -} - -void VFindReplaceDialog::replace() -{ - QString text = m_findEdit->text(); - if (text.isEmpty() || !m_replaceAvailable) { - return; - } - QString replaceText = m_replaceEdit->text(); - emit replace(text, m_options, replaceText, false); -} - -void VFindReplaceDialog::replaceFind() -{ - QString text = m_findEdit->text(); - if (text.isEmpty() || !m_replaceAvailable) { - return; - } - QString replaceText = m_replaceEdit->text(); - emit replace(text, m_options, replaceText, true); -} - -void VFindReplaceDialog::replaceAll() -{ - QString text = m_findEdit->text(); - if (text.isEmpty() || !m_replaceAvailable) { - return; - } - QString replaceText = m_replaceEdit->text(); - emit replaceAll(text, m_options, replaceText); -} - -void VFindReplaceDialog::updateState(DocType p_docType, bool p_editMode) -{ - if (p_editMode || p_docType == DocType::Html) { - m_wholeWordOnlyCheck->setEnabled(true); - m_regularExpressionCheck->setEnabled(true); - } else if (p_docType == DocType::Markdown) { - m_wholeWordOnlyCheck->setEnabled(false); - m_regularExpressionCheck->setEnabled(false); - } - - m_replaceAvailable = p_editMode; -} diff --git a/src/dialog/vfindreplacedialog.h b/src/dialog/vfindreplacedialog.h deleted file mode 100644 index 59cd0397..00000000 --- a/src/dialog/vfindreplacedialog.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef VFINDREPLACEDIALOG_H -#define VFINDREPLACEDIALOG_H - -#include -#include -#include "vconstants.h" - -class QLineEdit; -class QPushButton; -class QCheckBox; - -class VFindReplaceDialog : public QWidget -{ - Q_OBJECT -public: - explicit VFindReplaceDialog(QWidget *p_parent = 0); - void setOption(FindOption p_opt, bool p_enabled); - // Update the options enabled/disabled state according to current - // edit tab. - void updateState(DocType p_docType, bool p_editMode); - -signals: - void dialogClosed(); - void findTextChanged(const QString &p_text, uint p_options); - void findOptionChanged(uint p_options); - void findNext(const QString &p_text, uint p_options, bool p_forward); - void replace(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext); - void replaceAll(const QString &p_text, uint p_options, - const QString &p_replaceText); - -protected: - void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; - -public slots: - void closeDialog(); - void openDialog(QString p_text = ""); - void findNext(); - void findPrevious(); - void replace(); - void replaceFind(); - void replaceAll(); - -private slots: - void handleFindTextChanged(const QString &p_text); - void advancedBtnToggled(bool p_checked); - void optionBoxToggled(int p_state); - -private: - void setupUI(); - // Bit OR of FindOption - uint m_options; - bool m_replaceAvailable; - - QLineEdit *m_findEdit; - QLineEdit *m_replaceEdit; - QPushButton *m_findNextBtn; - QPushButton *m_findPrevBtn; - QPushButton *m_replaceBtn; - QPushButton *m_replaceFindBtn; - QPushButton *m_replaceAllBtn; - QPushButton *m_advancedBtn; - QPushButton *m_closeBtn; - QCheckBox *m_caseSensitiveCheck; - QCheckBox *m_wholeWordOnlyCheck; - QCheckBox *m_regularExpressionCheck; - QCheckBox *m_incrementalSearchCheck; -}; - -#endif // VFINDREPLACEDIALOG_H diff --git a/src/dialog/vinsertimagedialog.cpp b/src/dialog/vinsertimagedialog.cpp deleted file mode 100644 index 5a82f04f..00000000 --- a/src/dialog/vinsertimagedialog.cpp +++ /dev/null @@ -1,267 +0,0 @@ -#include -#include -#include -#include -#include -#include "vinsertimagedialog.h" -#include "utils/vutils.h" -#include "vlineedit.h" -#include "vdownloader.h" - -VInsertImageDialog::VInsertImageDialog(const QString &p_title, - const QString &p_imageTitle, - const QString &p_imagePath, - bool p_browsable, - QWidget *p_parent) - : QDialog(p_parent), - m_image(NULL), - m_browsable(p_browsable), - m_timer(NULL) -{ - setupUI(p_title, p_imageTitle, p_imagePath); - - connect(m_imageTitleEdit, &QLineEdit::textChanged, - this, &VInsertImageDialog::handleInputChanged); - - if (m_browsable) { - m_timer = new QTimer(this); - m_timer->setSingleShot(true); - m_timer->setInterval(500 /* ms */); - connect(m_timer, &QTimer::timeout, - this, &VInsertImageDialog::handlePathEditChanged); - - connect(m_pathEdit, &QLineEdit::textChanged, - this, [this]() { - m_timer->stop(); - - setImage(QImage()); - if (m_pathEdit->text().isEmpty()) { - return; - } - - m_timer->start(); - }); - - connect(browseBtn, &QPushButton::clicked, - this, &VInsertImageDialog::handleBrowseBtnClicked); - - fetchImageFromClipboard(); - } - - handleInputChanged(); -} - -VInsertImageDialog::~VInsertImageDialog() -{ - if (m_image) { - delete m_image; - m_image = NULL; - } -} - -void VInsertImageDialog::setupUI(const QString &p_title, - const QString &p_imageTitle, - const QString &p_imagePath) -{ - QLabel *pathLabel = new QLabel(tr("&From:")); - m_pathEdit = new QLineEdit(p_imagePath); - pathLabel->setBuddy(m_pathEdit); - browseBtn = new QPushButton(tr("&Browse")); - m_pathEdit->setReadOnly(!m_browsable); - browseBtn->setEnabled(m_browsable); - - QLabel *imageTitleLabel = new QLabel(tr("&Image title:")); - m_imageTitleEdit = new VLineEdit(p_imageTitle); - m_imageTitleEdit->selectAll(); - imageTitleLabel->setBuddy(m_imageTitleEdit); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_imageTitleRegExp), - m_imageTitleEdit); - m_imageTitleEdit->setValidator(validator); - - QGridLayout *topLayout = new QGridLayout(); - topLayout->addWidget(pathLabel, 0, 0); - topLayout->addWidget(m_pathEdit, 0, 1); - topLayout->addWidget(browseBtn, 0, 2); - topLayout->addWidget(imageTitleLabel, 1, 0); - topLayout->addWidget(m_imageTitleEdit, 1, 1, 1, 2); - topLayout->setColumnStretch(0, 0); - topLayout->setColumnStretch(1, 1); - topLayout->setColumnStretch(2, 0); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - m_btnBox->button(QDialogButtonBox::Ok)->setProperty("SpecialBtn", true); - - imagePreviewLabel = new QLabel(); - imagePreviewLabel->setVisible(false); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_btnBox); - mainLayout->addWidget(imagePreviewLabel); - setLayout(mainLayout); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setWindowTitle(p_title); - - m_imageTitleEdit->setFocus(); -} - -void VInsertImageDialog::handleInputChanged() -{ - QString title = m_imageTitleEdit->getEvaluatedText(); - QRegExp reg(VUtils::c_imageTitleRegExp); - bool titleOk = reg.exactMatch(title); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(titleOk && m_image); -} - -QString VInsertImageDialog::getImageTitleInput() const -{ - return m_imageTitleEdit->getEvaluatedText(); -} - -QString VInsertImageDialog::getPathInput() const -{ - return m_pathEdit->text(); -} - -void VInsertImageDialog::handleBrowseBtnClicked() -{ - static QString lastPath = QDir::homePath(); - QString filePath = QFileDialog::getOpenFileName(this, tr("Select The Image To Be Inserted"), - lastPath, tr("Images (*.png *.xpm *.jpg *.bmp *.gif)")); - if (filePath.isEmpty()) { - return; - } - - // Update lastPath - lastPath = QFileInfo(filePath).path(); - - m_imageType = ImageType::LocalFile; - - m_pathEdit->setText(filePath); - - m_imageTitleEdit->setFocus(); -} - -void VInsertImageDialog::setImage(const QImage &image) -{ - if (image.isNull()) { - imagePreviewLabel->setVisible(false); - if (m_image) { - delete m_image; - m_image = NULL; - } - - handleInputChanged(); - return; - } - - int width = 512 * VUtils::calculateScaleFactor(); - QSize previewSize(width, width); - if (!m_image) { - m_image = new QImage(image); - } else { - *m_image = image; - } - - QPixmap pixmap; - if (image.width() > width || image.height() > width) { - pixmap = QPixmap::fromImage(m_image->scaled(previewSize, Qt::KeepAspectRatio)); - } else { - pixmap = QPixmap::fromImage(*m_image); - } - - imagePreviewLabel->setPixmap(pixmap); - imagePreviewLabel->setVisible(true); - - handleInputChanged(); -} - -void VInsertImageDialog::imageDownloaded(const QByteArray &data) -{ - m_imageType = ImageType::ImageData; - setImage(QImage::fromData(data)); -} - -QImage VInsertImageDialog::getImage() const -{ - if (!m_image) { - return QImage(); - } else return *m_image; -} - -void VInsertImageDialog::fetchImageFromClipboard() -{ - if (!m_browsable || !m_pathEdit->text().isEmpty()) { - return; - } - - Q_ASSERT(!m_image); - - QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - - QUrl url; - - if (mimeData->hasImage()) { - QImage im = qvariant_cast(mimeData->imageData()); - if (im.isNull()) { - return; - } - - setImage(im); - m_imageType = ImageType::ImageData; - qDebug() << "fetch image data from clipboard to insert"; - return; - } else if (mimeData->hasUrls()) { - QList urls = mimeData->urls(); - if (urls.size() != 1) { - return; - } - - url = urls[0]; - } else if (mimeData->hasText()) { - url = QUrl(mimeData->text()); - } - - if (url.isValid()) { - if (url.isLocalFile()) { - m_pathEdit->setText(url.toLocalFile()); - } else { - m_pathEdit->setText(url.toString()); - } - } -} - -void VInsertImageDialog::handlePathEditChanged() -{ - QString text = m_pathEdit->text(); - QUrl url = QUrl::fromUserInput(text); - if (!url.isValid()) { - setImage(QImage()); - return; - } - - QImage image(text); - if (image.isNull()) { - setImage(QImage()); - // Try to treat it as network image. - m_imageType = ImageType::ImageData; - VDownloader *downloader = new VDownloader(this); - connect(downloader, &VDownloader::downloadFinished, - this, &VInsertImageDialog::imageDownloaded); - downloader->download(url.toString()); - qDebug() << "try to fetch network image to insert" << text; - } else { - // Local image path. - setImage(image); - m_imageType = ImageType::LocalFile; - qDebug() << "fetch local file image to insert" << text; - } - - handleInputChanged(); -} diff --git a/src/dialog/vinsertimagedialog.h b/src/dialog/vinsertimagedialog.h deleted file mode 100644 index 1b0f6222..00000000 --- a/src/dialog/vinsertimagedialog.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef VINSERTIMAGEDIALOG_H -#define VINSERTIMAGEDIALOG_H - -#include -#include -#include -#include - -class QLabel; -class QLineEdit; -class VLineEdit; -class QPushButton; -class QDialogButtonBox; -class QTimer; - -class VInsertImageDialog : public QDialog -{ - Q_OBJECT -public: - enum ImageType - { - LocalFile = 0, - ImageData - }; - - VInsertImageDialog(const QString &p_title, - const QString &p_imageTitle, - const QString &p_imagePath, - bool p_browsable = true, - QWidget *p_parent = nullptr); - - ~VInsertImageDialog(); - - QString getImageTitleInput() const; - - QString getPathInput() const; - - void setImage(const QImage &image); - - QImage getImage() const; - - VInsertImageDialog::ImageType getImageType() const; - -public slots: - void imageDownloaded(const QByteArray &data); - -private slots: - void handleInputChanged(); - - void handleBrowseBtnClicked(); - - void handlePathEditChanged(); - -private: - void setupUI(const QString &p_title, - const QString &p_imageTitle, - const QString &p_imagePath); - - void fetchImageFromClipboard(); - - VLineEdit *m_imageTitleEdit; - QLineEdit *m_pathEdit; - QPushButton *browseBtn; - QDialogButtonBox *m_btnBox; - QLabel *imagePreviewLabel; - - QImage *m_image; - - // Whether enable the browse action. - bool m_browsable; - - ImageType m_imageType; - - // Timer for path edit change. - QTimer *m_timer; -}; - -inline VInsertImageDialog::ImageType VInsertImageDialog::getImageType() const -{ - return m_imageType; -} - -#endif // VINSERTIMAGEDIALOG_H diff --git a/src/dialog/vinsertlinkdialog.cpp b/src/dialog/vinsertlinkdialog.cpp deleted file mode 100644 index e7382431..00000000 --- a/src/dialog/vinsertlinkdialog.cpp +++ /dev/null @@ -1,142 +0,0 @@ -#include "vinsertlinkdialog.h" - -#include - -#include "vlineedit.h" - -VInsertLinkDialog::VInsertLinkDialog(const QString &p_title, - const QString &p_text, - const QString &p_info, - const QString &p_linkText, - const QString &p_linkUrl, - QWidget *p_parent) - : QDialog(p_parent) -{ - setupUI(p_title, p_text, p_info, p_linkText, p_linkUrl); - - fetchLinkFromClipboard(); - - handleInputChanged(); -} - -void VInsertLinkDialog::setupUI(const QString &p_title, - const QString &p_text, - const QString &p_info, - const QString &p_linkText, - const QString &p_linkUrl) -{ - QLabel *textLabel = NULL; - if (!p_text.isEmpty()) { - textLabel = new QLabel(p_text); - textLabel->setWordWrap(true); - } - - QLabel *infoLabel = NULL; - if (!p_info.isEmpty()) { - infoLabel = new QLabel(p_info); - infoLabel->setWordWrap(true); - } - - m_linkTextEdit = new VLineEdit(p_linkText); - m_linkTextEdit->selectAll(); - - m_linkUrlEdit = new QLineEdit(p_linkUrl); - m_linkUrlEdit->setToolTip(tr("Absolute or relative path of the link")); - - QFormLayout *inputLayout = new QFormLayout(); - inputLayout->addRow(tr("&Text:"), m_linkTextEdit); - inputLayout->addRow(tr("&URL:"), m_linkUrlEdit); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - m_linkTextEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QVBoxLayout *mainLayout = new QVBoxLayout; - if (textLabel) { - mainLayout->addWidget(textLabel); - } - - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - - mainLayout->addLayout(inputLayout); - mainLayout->addWidget(m_btnBox); - - setLayout(mainLayout); - setWindowTitle(p_title); - - connect(m_linkTextEdit, &QLineEdit::textChanged, - this, &VInsertLinkDialog::handleInputChanged); - connect(m_linkUrlEdit, &QLineEdit::textChanged, - this, &VInsertLinkDialog::handleInputChanged); -} - -void VInsertLinkDialog::handleInputChanged() -{ - bool textOk = true; - if (m_linkTextEdit->getEvaluatedText().isEmpty()) { - textOk = false; - } - - bool urlOk = true; - if (m_linkUrlEdit->text().isEmpty()) { - urlOk = false; - } - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(textOk && urlOk); -} - -void VInsertLinkDialog::fetchLinkFromClipboard() -{ - if (!m_linkUrlEdit->text().isEmpty() - || !m_linkTextEdit->text().isEmpty()) { - return; - } - - QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - - if (!mimeData->hasText()) { - return; - } - - QString text = mimeData->text(); - if (text.isEmpty()) { - return; - } - - QUrl url = QUrl::fromUserInput(text); - if (url.isValid()) { - if (m_linkUrlEdit->text().isEmpty()) { - m_linkUrlEdit->setText(text); - } - } else if (m_linkTextEdit->text().isEmpty()) { - m_linkTextEdit->setText(text); - } -} - -QString VInsertLinkDialog::getLinkText() const -{ - return m_linkTextEdit->getEvaluatedText(); -} - -QString VInsertLinkDialog::getLinkUrl() const -{ - return m_linkUrlEdit->text(); -} - -void VInsertLinkDialog::showEvent(QShowEvent *p_event) -{ - QDialog::showEvent(p_event); - - if (!m_linkTextEdit->text().isEmpty() && m_linkUrlEdit->text().isEmpty()) { - m_linkUrlEdit->setFocus(); - } -} diff --git a/src/dialog/vinsertlinkdialog.h b/src/dialog/vinsertlinkdialog.h deleted file mode 100644 index 8c2fe588..00000000 --- a/src/dialog/vinsertlinkdialog.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef VINSERTLINKDIALOG_H -#define VINSERTLINKDIALOG_H - -#include -#include - -class VLineEdit; -class QLineEdit; -class QDialogButtonBox; -class QShowEvent; - -class VInsertLinkDialog : public QDialog -{ - Q_OBJECT -public: - VInsertLinkDialog(const QString &p_title, - const QString &p_text, - const QString &p_info, - const QString &p_linkText, - const QString &p_linkUrl, - QWidget *p_parent = nullptr); - - QString getLinkText() const; - - QString getLinkUrl() const; - -protected: - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - void handleInputChanged(); - -private: - void setupUI(const QString &p_title, - const QString &p_text, - const QString &p_info, - const QString &p_linkText, - const QString &p_linkUrl); - - // Infer link text/url from clipboard only when text and url are both empty. - void fetchLinkFromClipboard(); - - VLineEdit *m_linkTextEdit; - - QLineEdit *m_linkUrlEdit; - - QDialogButtonBox *m_btnBox; -}; - -#endif // VINSERTLINKDIALOG_H diff --git a/src/dialog/vnewdirdialog.cpp b/src/dialog/vnewdirdialog.cpp deleted file mode 100644 index dc5e6742..00000000 --- a/src/dialog/vnewdirdialog.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include -#include "vnewdirdialog.h" -#include "vdirectory.h" -#include "vconfigmanager.h" -#include "vlineedit.h" -#include "utils/vutils.h" - -extern VConfigManager *g_config; - -VNewDirDialog::VNewDirDialog(const QString &title, - const QString &info, - const QString &defaultName, - VDirectory *directory, - QWidget *parent) - : QDialog(parent), title(title), info(info), defaultName(defaultName), - m_directory(directory) -{ - setupUI(); - - connect(m_nameEdit, &QLineEdit::textChanged, this, &VNewDirDialog::handleInputChanged); - - handleInputChanged(); -} - -void VNewDirDialog::setupUI() -{ - QLabel *infoLabel = NULL; - if (!info.isEmpty()) { - infoLabel = new QLabel(info); - infoLabel->setWordWrap(true); - } - - QLabel *nameLabel = new QLabel(tr("Folder &name:")); - m_nameEdit = new VLineEdit(defaultName); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_nameEdit); - m_nameEdit->setValidator(validator); - m_nameEdit->selectAll(); - nameLabel->setBuddy(m_nameEdit); - - m_warnLabel = new QLabel(); - m_warnLabel->setWordWrap(true); - m_warnLabel->hide(); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - m_btnBox->button(QDialogButtonBox::Ok)->setProperty("SpecialBtn", true); - - QHBoxLayout *topLayout = new QHBoxLayout(); - topLayout->addWidget(nameLabel); - topLayout->addWidget(m_nameEdit); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - m_nameEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_warnLabel); - mainLayout->addWidget(m_btnBox); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setLayout(mainLayout); - setWindowTitle(title); -} - -void VNewDirDialog::handleInputChanged() -{ - bool showWarnLabel = false; - QString name = m_nameEdit->getEvaluatedText(); - bool nameOk = !name.isEmpty(); - if (nameOk) { - // Check if the name conflicts with existing directory name. - // Case-insensitive when creating folder. - QString warnText; - if (m_directory->findSubDirectory(name, false)) { - nameOk = false; - warnText = tr("WARNING: " - "Name (case-insensitive) %3 already exists. " - "Please choose another name.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } else if (!VUtils::checkFileNameLegal(name)) { - // Check if evaluated name contains illegal characters. - nameOk = false; - warnText = tr("WARNING: " - "Name %3 contains illegal characters " - "(after magic word evaluation).") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } - - if (!nameOk) { - showWarnLabel = true; - m_warnLabel->setText(warnText); - } - } - - m_warnLabel->setVisible(showWarnLabel); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(nameOk); -} - -QString VNewDirDialog::getNameInput() const -{ - return m_nameEdit->getEvaluatedText(); -} diff --git a/src/dialog/vnewdirdialog.h b/src/dialog/vnewdirdialog.h deleted file mode 100644 index 8594c594..00000000 --- a/src/dialog/vnewdirdialog.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef VNEWDIRDIALOG_H -#define VNEWDIRDIALOG_H - -#include - -class QLabel; -class VLineEdit; -class QDialogButtonBox; -class QString; -class VDirectory; - -class VNewDirDialog : public QDialog -{ - Q_OBJECT -public: - VNewDirDialog(const QString &title, - const QString &info, - const QString &defaultName, - VDirectory *directory, - QWidget *parent = 0); - - QString getNameInput() const; - -private slots: - void handleInputChanged(); - -private: - void setupUI(); - - VLineEdit *m_nameEdit; - QDialogButtonBox *m_btnBox; - - QLabel *m_warnLabel; - - QString title; - QString info; - QString defaultName; - - VDirectory *m_directory; -}; - -#endif // VNEWDIRDIALOG_H diff --git a/src/dialog/vnewfiledialog.cpp b/src/dialog/vnewfiledialog.cpp deleted file mode 100644 index 8f424627..00000000 --- a/src/dialog/vnewfiledialog.cpp +++ /dev/null @@ -1,285 +0,0 @@ -#include -#include "vnewfiledialog.h" -#include "vconfigmanager.h" -#include "vdirectory.h" -#include "vlineedit.h" -#include "utils/vutils.h" -#include "utils/vmetawordmanager.h" -#include "utils/viconutils.h" - -extern VConfigManager *g_config; - -extern VMetaWordManager *g_mwMgr; - -QString VNewFileDialog::s_lastTemplateFile; - - -VNewFileDialog::VNewFileDialog(const QString &p_title, - const QString &p_info, - const QString &p_defaultName, - VDirectory *p_directory, - QWidget *p_parent) - : QDialog(p_parent), - m_currentTemplateType(DocType::Unknown), - m_directory(p_directory) -{ - setupUI(p_title, p_info, p_defaultName); - - connect(m_nameEdit, &VLineEdit::textChanged, this, &VNewFileDialog::handleInputChanged); - - connect(m_templateCB, static_cast(&QComboBox::currentIndexChanged), - this, &VNewFileDialog::handleCurrentTemplateChanged); - - handleInputChanged(); - - tryToSelectLastTemplate(); -} - -void VNewFileDialog::setupUI(const QString &p_title, - const QString &p_info, - const QString &p_defaultName) -{ - QLabel *infoLabel = NULL; - if (!p_info.isEmpty()) { - infoLabel = new QLabel(p_info); - } - - // Name. - m_nameEdit = new VLineEdit(p_defaultName); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_nameEdit); - m_nameEdit->setValidator(validator); - int dotIndex = p_defaultName.lastIndexOf('.'); - m_nameEdit->setSelection(0, (dotIndex == -1) ? p_defaultName.size() : dotIndex); - - // Template. - m_templateCB = VUtils::getComboBox(); - m_templateCB->setToolTip(tr("Choose a template (magic word supported)")); - m_templateCB->setSizeAdjustPolicy(QComboBox::AdjustToContents); - - QPushButton *templateBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/manage_template.svg"), - ""); - templateBtn->setToolTip(tr("Manage Templates")); - templateBtn->setProperty("FlatBtn", true); - connect(templateBtn, &QPushButton::clicked, - this, [this]() { - QUrl url = QUrl::fromLocalFile(g_config->getTemplateConfigFolder()); - QDesktopServices::openUrl(url); - }); - - QHBoxLayout *tempBtnLayout = new QHBoxLayout(); - tempBtnLayout->addWidget(m_templateCB); - tempBtnLayout->addWidget(templateBtn); - tempBtnLayout->addStretch(); - - m_templateEdit = new QTextEdit(); - m_templateEdit->setReadOnly(true); - - QVBoxLayout *templateLayout = new QVBoxLayout(); - templateLayout->addLayout(tempBtnLayout); - templateLayout->addWidget(m_templateEdit); - - m_templateEdit->hide(); - - // InsertTitle. - m_insertTitleCB = new QCheckBox(tr("Insert note name as title (for Markdown only)")); - m_insertTitleCB->setToolTip(tr("Insert note name into the new note as a title")); - m_insertTitleCB->setChecked(g_config->getInsertTitleFromNoteName()); - connect(m_insertTitleCB, &QCheckBox::stateChanged, - this, [this](int p_state) { - g_config->setInsertTitleFromNoteName(p_state == Qt::Checked); - }); - - QFormLayout *topLayout = new QFormLayout(); - topLayout->addRow(tr("Note &name:"), m_nameEdit); - topLayout->addWidget(m_insertTitleCB); - topLayout->addRow(tr("Template:"), templateLayout); - - m_nameEdit->setMinimumWidth(m_insertTitleCB->sizeHint().width()); - - m_warnLabel = new QLabel(); - m_warnLabel->setWordWrap(true); - m_warnLabel->hide(); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, - this, [this]() { - s_lastTemplateFile = m_templateCB->currentData().toString(); - QDialog::accept(); - }); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - m_templateCB->setMaximumWidth(okBtn->sizeHint().width() * 4); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_warnLabel); - mainLayout->addWidget(m_btnBox); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setLayout(mainLayout); - - setWindowTitle(p_title); -} - -void VNewFileDialog::handleInputChanged() -{ - bool showWarnLabel = false; - const QString name = m_nameEdit->getEvaluatedText(); - bool nameOk = !name.isEmpty(); - if (nameOk) { - // Check if the name conflicts with existing note name. - // Case-insensitive when creating note. - QString warnText; - if (m_directory->findFile(name, false)) { - nameOk = false; - warnText = tr("WARNING: " - "Name (case-insensitive) %3 already exists. " - "Please choose another name.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } else if (!VUtils::checkFileNameLegal(name)) { - // Check if evaluated name contains illegal characters. - nameOk = false; - warnText = tr("WARNING: " - "Name %3 contains illegal characters " - "(after magic word evaluation).") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } - - if (!nameOk) { - showWarnLabel = true; - m_warnLabel->setText(warnText); - } - } - - m_warnLabel->setVisible(showWarnLabel); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(nameOk); - - if (nameOk) { - updateTemplates(VUtils::docTypeFromName(name)); - } -} - -QString VNewFileDialog::getNameInput() const -{ - return m_nameEdit->getEvaluatedText(); -} - -bool VNewFileDialog::getInsertTitleInput() const -{ - return m_insertTitleCB->isEnabled() && m_insertTitleCB->isChecked(); -} - -void VNewFileDialog::updateTemplates(DocType p_type) -{ - if (m_currentTemplateType == p_type) { - return; - } - - m_currentTemplateType = p_type; - - // Clear the combo. - m_templateCB->clear(); - - // Add None item. - m_templateCB->addItem(tr("None"), "None"); - - if (m_currentTemplateType == DocType::Unknown) { - return; - } - - int idx = 1; - auto templates = g_config->getNoteTemplates(m_currentTemplateType); - for (auto const & tp : templates) { - m_templateCB->addItem(tp, tp); - m_templateCB->setItemData(idx++, tp, Qt::ToolTipRole); - } -} - -void VNewFileDialog::handleCurrentTemplateChanged(int p_idx) -{ - if (p_idx == -1) { - m_templateEdit->hide(); - enableInsertTitleCB(false); - return; - } - - QString file = m_templateCB->itemData(p_idx).toString(); - if (file == "None") { - m_templateEdit->hide(); - enableInsertTitleCB(false); - return; - } - - // Read the template file. - QString filePath = QDir(g_config->getTemplateConfigFolder()).filePath(file); - m_template = VUtils::readFileFromDisk(filePath); - DocType type = VUtils::docTypeFromName(file); - switch (type) { - case DocType::Html: - m_templateEdit->setHtml(m_template); - break; - - case DocType::Markdown: - m_templateEdit->setPlainText(m_template); - break; - - default: - m_templateEdit->setPlainText(m_template); - break; - } - - m_templateEdit->show(); - enableInsertTitleCB(true); -} - -void VNewFileDialog::enableInsertTitleCB(bool p_hasTemplate) -{ - m_insertTitleCB->setEnabled(!p_hasTemplate - && VUtils::docTypeFromName(m_nameEdit->getEvaluatedText()) - == DocType::Markdown); -} - -bool VNewFileDialog::isTemplateUsed() const -{ - QString file = m_templateCB->currentData().toString(); - return !(file.isEmpty() || file == "None"); -} - -QString VNewFileDialog::getTemplate() const -{ - QString name = m_nameEdit->getEvaluatedText(); - QHash overriddenTable; - overriddenTable.insert("note", name); - overriddenTable.insert("no", QFileInfo(name).completeBaseName()); - return g_mwMgr->evaluate(m_template, overriddenTable); -} - -void VNewFileDialog::tryToSelectLastTemplate() -{ - Q_ASSERT(m_templateCB->count() > 0 - && m_templateCB->itemData(0).toString() == "None"); - if (s_lastTemplateFile.isEmpty() || s_lastTemplateFile == "None") { - m_templateCB->setCurrentIndex(0); - return; - } - - int idx = m_templateCB->findData(s_lastTemplateFile); - if (idx != -1) { - m_templateCB->setCurrentIndex(idx); - } else { - s_lastTemplateFile.clear(); - } -} diff --git a/src/dialog/vnewfiledialog.h b/src/dialog/vnewfiledialog.h deleted file mode 100644 index 729416dd..00000000 --- a/src/dialog/vnewfiledialog.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef VNEWFILEDIALOG_H -#define VNEWFILEDIALOG_H - -#include - -#include "vconstants.h" - -class QLabel; -class VLineEdit; -class QDialogButtonBox; -class QCheckBox; -class VDirectory; -class QComboBox; -class QTextEdit; - -class VNewFileDialog : public QDialog -{ - Q_OBJECT -public: - VNewFileDialog(const QString &p_title, - const QString &p_info, - const QString &p_defaultName, - VDirectory *p_directory, - QWidget *p_parent = 0); - - QString getNameInput() const; - - bool getInsertTitleInput() const; - - // Whether user choose a note template. - bool isTemplateUsed() const; - - // Get the template content (after magic words evaluated) user chose. - QString getTemplate() const; - -private slots: - void handleInputChanged(); - - void handleCurrentTemplateChanged(int p_idx); - -private: - void setupUI(const QString &p_title, - const QString &p_info, - const QString &p_defaultName); - - // Update the templates according to @p_type. - void updateTemplates(DocType p_type); - - void enableInsertTitleCB(bool p_hasTemplate); - - void tryToSelectLastTemplate(); - - VLineEdit *m_nameEdit; - - QComboBox *m_templateCB; - - // Used for template preview. - QTextEdit *m_templateEdit; - - QCheckBox *m_insertTitleCB; - - QPushButton *okBtn; - QDialogButtonBox *m_btnBox; - - QLabel *m_warnLabel; - - // Template content. - QString m_template; - - // Doc type of current template. - DocType m_currentTemplateType; - - // Last chosen template file. - static QString s_lastTemplateFile; - - VDirectory *m_directory; -}; - -#endif // VNEWFILEDIALOG_H diff --git a/src/dialog/vnewnotebookdialog.cpp b/src/dialog/vnewnotebookdialog.cpp deleted file mode 100644 index e1728f7e..00000000 --- a/src/dialog/vnewnotebookdialog.cpp +++ /dev/null @@ -1,353 +0,0 @@ -#include -#include -#include "vnewnotebookdialog.h" -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "vnotebook.h" -#include "vlineedit.h" - -extern VConfigManager *g_config; - -VNewNotebookDialog::VNewNotebookDialog(const QString &title, const QString &info, - const QString &defaultName, const QString &defaultPath, - const QVector &p_notebooks, - QWidget *parent) - : QDialog(parent), - defaultName(defaultName), defaultPath(defaultPath), - m_importNotebook(false), m_manualPath(false), m_manualName(false), - m_notebooks(p_notebooks) -{ - setupUI(title, info); - - connect(m_nameEdit, &QLineEdit::textChanged, this, &VNewNotebookDialog::handleInputChanged); - connect(pathEdit, &QLineEdit::textChanged, this, &VNewNotebookDialog::handleInputChanged); - connect(browseBtn, &QPushButton::clicked, this, &VNewNotebookDialog::handleBrowseBtnClicked); - - handleInputChanged(); -} - -void VNewNotebookDialog::setupUI(const QString &p_title, const QString &p_info) -{ - QLabel *infoLabel = NULL; - if (!p_info.isEmpty()) { - infoLabel = new QLabel(p_info); - infoLabel->setWordWrap(true); - } - - QLabel *nameLabel = new QLabel(tr("Notebook &name:")); - m_nameEdit = new VLineEdit(defaultName); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_nameEdit); - m_nameEdit->setValidator(validator); - nameLabel->setBuddy(m_nameEdit); - - QLabel *pathLabel = new QLabel(tr("Notebook &root folder:")); - pathEdit = new QLineEdit(defaultPath); - pathLabel->setBuddy(pathEdit); - browseBtn = new QPushButton(tr("&Browse")); - - QLabel *imageFolderLabel = new QLabel(tr("&Image folder:")); - m_imageFolderEdit = new QLineEdit(); - imageFolderLabel->setBuddy(m_imageFolderEdit); - m_imageFolderEdit->setPlaceholderText(tr("Use global configuration (%1)") - .arg(g_config->getImageFolder())); - m_imageFolderEdit->setToolTip(tr("Set the name of the folder to hold images of all the notes in this notebook " - "(empty to use global configuration)")); - imageFolderLabel->setToolTip(m_imageFolderEdit->toolTip()); - validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), m_imageFolderEdit); - m_imageFolderEdit->setValidator(validator); - - QLabel *attachmentFolderLabel = new QLabel(tr("&Attachment folder:")); - m_attachmentFolderEdit = new QLineEdit(); - attachmentFolderLabel->setBuddy(m_attachmentFolderEdit); - m_attachmentFolderEdit->setPlaceholderText(tr("Use global configuration (%1)") - .arg(g_config->getAttachmentFolder())); - m_attachmentFolderEdit->setToolTip(tr("Set the name of the folder to hold attachments of all the notes in this notebook " - "(empty to use global configuration, read-only once created)")); - attachmentFolderLabel->setToolTip(m_attachmentFolderEdit->toolTip()); - validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), m_attachmentFolderEdit); - m_attachmentFolderEdit->setValidator(validator); - - QGridLayout *topLayout = new QGridLayout(); - topLayout->addWidget(nameLabel, 0, 0); - topLayout->addWidget(m_nameEdit, 0, 1, 1, 2); - topLayout->addWidget(pathLabel, 1, 0); - topLayout->addWidget(pathEdit, 1, 1); - topLayout->addWidget(browseBtn, 1, 2); - topLayout->addWidget(imageFolderLabel, 2, 0); - topLayout->addWidget(m_imageFolderEdit, 2, 1); - topLayout->addWidget(attachmentFolderLabel, 3, 0); - topLayout->addWidget(m_attachmentFolderEdit, 3, 1); - - // Warning label. - m_warnLabel = new QLabel(); - m_warnLabel->setWordWrap(true); - m_warnLabel->hide(); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - pathEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QVBoxLayout *mainLayout = new QVBoxLayout(this); - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_warnLabel); - mainLayout->addWidget(m_btnBox); - - // Will set the parent of above widgets properly. - setLayout(mainLayout); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setWindowTitle(p_title); -} - -QString VNewNotebookDialog::getNameInput() const -{ - return m_nameEdit->getEvaluatedText(); -} - -QString VNewNotebookDialog::getPathInput() const -{ - // absoluteFilePath() to convert the drive to upper case. - // cleanPath() to remove duplicate separator, '.', and '..'. - return QDir::cleanPath(QFileInfo(pathEdit->text()).absoluteFilePath()); -} - -QString VNewNotebookDialog::getImageFolder() const -{ - if (m_imageFolderEdit->isEnabled()) { - return m_imageFolderEdit->text(); - } else { - return QString(); - } -} - -QString VNewNotebookDialog::getAttachmentFolder() const -{ - if (m_attachmentFolderEdit->isEnabled()) { - return m_attachmentFolderEdit->text(); - } else { - return QString(); - } -} - -void VNewNotebookDialog::handleBrowseBtnClicked() -{ - static QString defaultPath; - if (defaultPath.isEmpty()) { - defaultPath = g_config->getVnoteNotebookFolderPath(); - if (!QFileInfo::exists(defaultPath)) { - defaultPath = QDir::homePath(); - } - } - - QString dirPath = QFileDialog::getExistingDirectory(this, - tr("Select Root Folder Of The Notebook"), - defaultPath, - QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); - - if (!dirPath.isEmpty()) { - m_manualPath = true; - pathEdit->setText(dirPath); - defaultPath = VUtils::basePathFromPath(dirPath); - } -} - -bool VNewNotebookDialog::isImportExistingNotebook() const -{ - return m_importNotebook; -} - -void VNewNotebookDialog::showEvent(QShowEvent *event) -{ - m_nameEdit->setFocus(); - QDialog::showEvent(event); -} - -void VNewNotebookDialog::handleInputChanged() -{ - QString warnText = tr("WARNING: The folder chosen is NOT empty! " - "It is highly recommended to use an EMPTY and EXCLUSIVE folder for a new notebook.") - .arg(g_config->c_warningTextStyle); - QString infoText = tr("INFO: The folder chosen seems to be a root " - "folder of a notebook created by VNote before. " - "VNote will try to import it by reading the configuration file.") - .arg("font-weight:bold;"); - bool pathOk = false; - bool configExist = false; - bool showWarnLabel = false; - - // User has input some texts. - if (pathEdit->isModified()) { - m_manualPath = true; - } - - if (m_nameEdit->isModified()) { - m_manualName = true; - } - - if (autoComplete()) { - return; - } - - QString path = pathEdit->text(); - if (!path.isEmpty()) { - if (QFileInfo::exists(path)) { - QDir dir(path); - QStringList files = dir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden); - if (files.isEmpty()) { - pathOk = true; - } else { - // Folder is not empty. - configExist = VConfigManager::directoryConfigExist(path); - showWarnLabel = true; - } - } else { - pathOk = true; - } - } - - if (configExist) { - pathOk = true; - m_warnLabel->setText(infoText); - } else { - m_warnLabel->setText(warnText); - } - - // Try to validate if this is a legal path on the OS. - if (pathOk) { - pathOk = VUtils::checkPathLegal(path); - if (!pathOk) { - showWarnLabel = true; - QString tmp = tr("WARNING: The path seems to be illegal. " - "Please choose another one.") - .arg(g_config->c_warningTextStyle); - m_warnLabel->setText(tmp); - } - } - - if (pathOk) { - // Check if this path has been in VNote. - int idx = -1; - for (idx = 0; idx < m_notebooks.size(); ++idx) { - if (VUtils::equalPath(m_notebooks[idx]->getPath(), path)) { - break; - } - } - - if (idx < m_notebooks.size()) { - pathOk = false; - showWarnLabel = true; - QString existText = tr("WARNING: The folder chosen has already been a root folder " - "of existing notebook %3 in VNote.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(m_notebooks[idx]->getName()); - m_warnLabel->setText(existText); - } - } - - QString name = m_nameEdit->getEvaluatedText(); - bool nameOk = !name.isEmpty(); - if (pathOk && nameOk) { - // Check if the name conflicts with existing notebook name. - // Case-insensitive. - int idx = -1; - for (idx = 0; idx < m_notebooks.size(); ++idx) { - if (m_notebooks[idx]->getName().toLower() == name.toLower()) { - break; - } - } - - QString warnText; - if (idx < m_notebooks.size()) { - nameOk = false; - warnText = tr("WARNING: " - "Name (case-insensitive) %3 already exists. " - "Please choose another name.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } else if (!VUtils::checkFileNameLegal(name)) { - // Check if evaluated name contains illegal characters. - nameOk = false; - warnText = tr("WARNING: " - "Name %3 contains illegal characters " - "(after magic word evaluation).") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } - - if (!nameOk) { - showWarnLabel = true; - m_warnLabel->setText(warnText); - } - } - - m_warnLabel->setVisible(showWarnLabel); - m_importNotebook = configExist; - m_imageFolderEdit->setEnabled(!m_importNotebook); - m_attachmentFolderEdit->setEnabled(!m_importNotebook); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(nameOk && pathOk); -} - -bool VNewNotebookDialog::autoComplete() -{ - QString nameText = m_nameEdit->getEvaluatedText(); - - if (m_manualPath) { - if (m_manualName) { - return false; - } - - // Set the name according to user-chosen path. - QString pathText = pathEdit->text(); - if (!pathText.isEmpty()) { - QString autoName = VUtils::directoryNameFromPath(pathText); - if (autoName != nameText) { - m_nameEdit->setText(autoName); - return true; - } - } - - return false; - } - - QString vnoteFolder = g_config->getVnoteNotebookFolderPath(); - QString pathText = pathEdit->text(); - if (!pathText.isEmpty() - && !VUtils::equalPath(vnoteFolder, VUtils::basePathFromPath(pathText))) { - return false; - } - - bool ret = false; - if (nameText.isEmpty()) { - if (m_manualName) { - return false; - } - - // Get a folder name under vnoteFolder and set it as the name of the notebook. - QString name = "vnotebook"; - name = VUtils::getDirNameWithSequence(vnoteFolder, name); - m_nameEdit->setText(name); - ret = true; - } else { - // Use the name as the folder name under vnoteFolder. - QString autoPath = QDir::cleanPath(QDir(vnoteFolder).filePath(nameText)); - if (autoPath != pathText) { - pathEdit->setText(autoPath); - ret = true; - } - } - - return ret; -} diff --git a/src/dialog/vnewnotebookdialog.h b/src/dialog/vnewnotebookdialog.h deleted file mode 100644 index 87d0d9b8..00000000 --- a/src/dialog/vnewnotebookdialog.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef VNEWNOTEBOOKDIALOG_H -#define VNEWNOTEBOOKDIALOG_H - -#include -#include - -class QLabel; -class QLineEdit; -class VLineEdit; -class QPushButton; -class QDialogButtonBox; -class VNotebook; - -class VNewNotebookDialog : public QDialog -{ - Q_OBJECT -public: - VNewNotebookDialog(const QString &title, const QString &info, const QString &defaultName, - const QString &defaultPath, const QVector &p_notebooks, - QWidget *parent = 0); - - QString getNameInput() const; - - QString getPathInput() const; - - // Whether import existing notebook by reading the config file. - bool isImportExistingNotebook() const; - - // Get the custom image folder for this notebook. - // Empty string indicates using global config. - QString getImageFolder() const; - - // Get the custom attachment folder for this notebook. - // Empty string indicates using global config. - QString getAttachmentFolder() const; - -private slots: - void handleBrowseBtnClicked(); - - // Handle the change of the name and path input. - void handleInputChanged(); - -protected: - void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; - -private: - void setupUI(const QString &p_title, const QString &p_info); - - // Should be called before enableOkButton() when path changed. - void checkRootFolder(const QString &p_path); - - // Try to figure out name and path. - // Returns true if name or path is modified. - bool autoComplete(); - - VLineEdit *m_nameEdit; - QLineEdit *pathEdit; - QPushButton *browseBtn; - QLabel *m_warnLabel; - QLineEdit *m_imageFolderEdit; - QLineEdit *m_attachmentFolderEdit; - QDialogButtonBox *m_btnBox; - - QString defaultName; - QString defaultPath; - - // Whether import existing notebook config file. - bool m_importNotebook; - - // True if user has change the content of the path edit. - bool m_manualPath; - - // True if user has change the content of the name edit. - bool m_manualName; - - // All existing notebooks in VNote. - const QVector &m_notebooks; -}; - -#endif // VNEWNOTEBOOKDIALOG_H diff --git a/src/dialog/vnotebookinfodialog.cpp b/src/dialog/vnotebookinfodialog.cpp deleted file mode 100644 index 0574bb7a..00000000 --- a/src/dialog/vnotebookinfodialog.cpp +++ /dev/null @@ -1,167 +0,0 @@ -#include -#include "vnotebookinfodialog.h" -#include "vnotebook.h" -#include "utils/vutils.h" -#include "vconfigmanager.h" -#include "vlineedit.h" - -extern VConfigManager *g_config; - -VNotebookInfoDialog::VNotebookInfoDialog(const QString &p_title, - const QString &p_info, - const VNotebook *p_notebook, - const QVector &p_notebooks, - QWidget *p_parent) - : QDialog(p_parent), m_notebook(p_notebook), - m_notebooks(p_notebooks) -{ - setupUI(p_title, p_info); - - connect(m_nameEdit, &QLineEdit::textChanged, - this, &VNotebookInfoDialog::handleInputChanged); - - handleInputChanged(); -} - -void VNotebookInfoDialog::setupUI(const QString &p_title, const QString &p_info) -{ - QLabel *infoLabel = NULL; - if (!p_info.isEmpty()) { - infoLabel = new QLabel(p_info); - } - - m_nameEdit = new VLineEdit(m_notebook->getName()); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_nameEdit); - m_nameEdit->setValidator(validator); - m_nameEdit->selectAll(); - - m_pathEdit = new QLineEdit(m_notebook->getPath()); - m_pathEdit->setReadOnly(true); - - // Image folder. - m_imageFolderEdit = new QLineEdit(m_notebook->getImageFolderConfig()); - m_imageFolderEdit->setPlaceholderText(tr("Use global configuration (%1)") - .arg(g_config->getImageFolder())); - m_imageFolderEdit->setToolTip(tr("Set the name of the folder to hold images of all the notes in this notebook " - "(empty to use global configuration)")); - validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), m_imageFolderEdit); - m_imageFolderEdit->setValidator(validator); - - // Attachment folder. - Q_ASSERT(!m_notebook->getAttachmentFolder().isEmpty()); - m_attachmentFolderEdit = new QLineEdit(m_notebook->getAttachmentFolder()); - m_attachmentFolderEdit->setPlaceholderText(tr("Use global configuration (%1)") - .arg(g_config->getAttachmentFolder())); - m_attachmentFolderEdit->setToolTip(tr("The folder to hold attachments of all the notes in this notebook")); - m_attachmentFolderEdit->setReadOnly(true); - - // Recycle bin folder. - QLineEdit *recycleBinFolderEdit = new QLineEdit(m_notebook->getRecycleBinFolder()); - recycleBinFolderEdit->setReadOnly(true); - recycleBinFolderEdit->setToolTip(tr("The folder to hold deleted files from within VNote of all the notes in this notebook")); - - // Created time. - QString createdTimeStr = VUtils::displayDateTime(const_cast(m_notebook)->getCreatedTimeUtc().toLocalTime()); - QLabel *createdTimeLabel = new QLabel(createdTimeStr); - - QFormLayout *topLayout = new QFormLayout(); - topLayout->addRow(tr("Notebook &name:"), m_nameEdit); - topLayout->addRow(tr("Notebook &root folder:"), m_pathEdit); - topLayout->addRow(tr("&Image folder:"), m_imageFolderEdit); - topLayout->addRow(tr("Attachment folder:"), m_attachmentFolderEdit); - topLayout->addRow(tr("Recycle bin folder:"), recycleBinFolderEdit); - topLayout->addRow(tr("Created time:"), createdTimeLabel); - - // Warning label. - m_warnLabel = new QLabel(); - m_warnLabel->setWordWrap(true); - m_warnLabel->hide(); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - m_pathEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_warnLabel); - mainLayout->addWidget(m_btnBox); - - setLayout(mainLayout); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setWindowTitle(p_title); -} - -void VNotebookInfoDialog::handleInputChanged() -{ - QString name = m_nameEdit->getEvaluatedText(); - bool nameOk = !name.isEmpty(); - bool showWarnLabel = false; - - if (nameOk && name != m_notebook->getName()) { - // Check if the name conflicts with existing notebook name. - // Case-insensitive. - int idx = -1; - for (idx = 0; idx < m_notebooks.size(); ++idx) { - if (m_notebooks[idx]->getName().toLower() == name.toLower()) { - break; - } - } - - QString warnText; - if (idx < m_notebooks.size() && m_notebooks[idx] != m_notebook) { - nameOk = false; - warnText = tr("WARNING: " - "Name (case-insensitive) %3 already exists. " - "Please choose another name.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } else if (!VUtils::checkFileNameLegal(name)) { - // Check if evaluated name contains illegal characters. - nameOk = false; - warnText = tr("WARNING: " - "Name %3 contains illegal characters " - "(after magic word evaluation).") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } - - if (!nameOk) { - showWarnLabel = true; - m_warnLabel->setText(warnText); - } - } - - m_warnLabel->setVisible(showWarnLabel); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(nameOk); -} - -QString VNotebookInfoDialog::getName() const -{ - return m_nameEdit->getEvaluatedText(); -} - -QString VNotebookInfoDialog::getImageFolder() const -{ - return m_imageFolderEdit->text(); -} - -void VNotebookInfoDialog::showEvent(QShowEvent *p_event) -{ - m_nameEdit->setFocus(); - QDialog::showEvent(p_event); -} - diff --git a/src/dialog/vnotebookinfodialog.h b/src/dialog/vnotebookinfodialog.h deleted file mode 100644 index d1b4c234..00000000 --- a/src/dialog/vnotebookinfodialog.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef VNOTEBOOKINFODIALOG_H -#define VNOTEBOOKINFODIALOG_H - -#include -#include - -class QLabel; -class QLineEdit; -class VLineEdit; -class QDialogButtonBox; -class QString; -class VNotebook; - -class VNotebookInfoDialog : public QDialog -{ - Q_OBJECT -public: - VNotebookInfoDialog(const QString &p_title, - const QString &p_info, - const VNotebook *p_notebook, - const QVector &p_notebooks, - QWidget *p_parent = 0); - - QString getName() const; - - // Get the custom image folder for this notebook. - // Empty string indicates using global config. - QString getImageFolder() const; - -private slots: - // Handle the change of the name and path input. - void handleInputChanged(); - -protected: - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - -private: - void setupUI(const QString &p_title, const QString &p_info); - - const VNotebook *m_notebook; - - VLineEdit *m_nameEdit; - QLineEdit *m_pathEdit; - QLineEdit *m_imageFolderEdit; - // Read-only. - QLineEdit *m_attachmentFolderEdit; - QLabel *m_warnLabel; - QDialogButtonBox *m_btnBox; - const QVector &m_notebooks; -}; - -#endif // VNOTEBOOKINFODIALOG_H diff --git a/src/dialog/vorphanfileinfodialog.cpp b/src/dialog/vorphanfileinfodialog.cpp deleted file mode 100644 index 5b7b561e..00000000 --- a/src/dialog/vorphanfileinfodialog.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "vorphanfileinfodialog.h" - -#include -#include "vorphanfile.h" -#include "vconfigmanager.h" -#include "utils/vutils.h" - -extern VConfigManager *g_config; - -VOrphanFileInfoDialog::VOrphanFileInfoDialog(const VOrphanFile *p_file, QWidget *p_parent) - : QDialog(p_parent), m_file(p_file) -{ - setupUI(); - - connect(m_imageFolderEdit, &QLineEdit::textChanged, - this, &VOrphanFileInfoDialog::handleInputChanged); - - handleInputChanged(); -} - -void VOrphanFileInfoDialog::setupUI() -{ - QFormLayout *topLayout = new QFormLayout(); - - QLabel *fileLabel = new QLabel(m_file->fetchPath()); - topLayout->addRow(tr("File:"), fileLabel); - - m_imageFolderEdit = new QLineEdit(m_file->getImageFolder()); - m_imageFolderEdit->setPlaceholderText(tr("Use global configuration (%1)") - .arg(g_config->getImageFolderExt())); - QString imgFolderTip = tr("Set the path of the image folder to store images " - "of this file.\nIf absolute path is used, " - "VNote will not manage those images." - "(empty to use global configuration)"); - m_imageFolderEdit->setToolTip(imgFolderTip); - topLayout->addRow(tr("&Image folder:"), m_imageFolderEdit); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - m_imageFolderEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_btnBox); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - - setLayout(mainLayout); - setWindowTitle(tr("External File Information")); -} - -QString VOrphanFileInfoDialog::getImageFolder() const -{ - return m_imageFolderEdit->text(); -} - -void VOrphanFileInfoDialog::handleInputChanged() -{ - bool ok = false; - QString imgFolder = m_imageFolderEdit->text(); - if (imgFolder.isEmpty() || VUtils::checkPathLegal(imgFolder)) { - ok = true; - } - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(ok); -} diff --git a/src/dialog/vorphanfileinfodialog.h b/src/dialog/vorphanfileinfodialog.h deleted file mode 100644 index f0d2a862..00000000 --- a/src/dialog/vorphanfileinfodialog.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef VORPHANFILEINFODIALOG_H -#define VORPHANFILEINFODIALOG_H - -#include - -class VOrphanFile; -class QDialogButtonBox; -class QLineEdit; - -class VOrphanFileInfoDialog : public QDialog -{ - Q_OBJECT - -public: - VOrphanFileInfoDialog(const VOrphanFile *p_file, QWidget *p_parent = 0); - - // Get the custom image folder for this external file. - // Empty string indicates using global config. - QString getImageFolder() const; - -private slots: - // Handle the change of the image folder input. - void handleInputChanged(); - -private: - void setupUI(); - - const VOrphanFile *m_file; - - QDialogButtonBox *m_btnBox; - QLineEdit *m_imageFolderEdit; -}; - -#endif // VORPHANFILEINFODIALOG_H diff --git a/src/dialog/vselectdialog.cpp b/src/dialog/vselectdialog.cpp deleted file mode 100644 index 018f82ff..00000000 --- a/src/dialog/vselectdialog.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include "vselectdialog.h" - -VSelectDialog::VSelectDialog(const QString &p_title, QWidget *p_parent) - : QDialog(p_parent), m_choice(-1) -{ - setupUI(p_title); -} - -void VSelectDialog::setupUI(const QString &p_title) -{ - m_mainLayout = new QVBoxLayout(); - - QPushButton *cancelBtn = new QPushButton(tr("Cancel")); - cancelBtn->setProperty("SelectionBtn", true); - connect(cancelBtn, &QPushButton::clicked, - this, &VSelectDialog::reject); - m_mainLayout->addWidget(cancelBtn); - - setLayout(m_mainLayout); - m_mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setWindowTitle(p_title); -} - -void VSelectDialog::addSelection(const QString &p_selectStr, int p_selectID) -{ - Q_ASSERT(p_selectID >= 0); - - QPushButton *btn = new QPushButton(p_selectStr); - btn->setProperty("SelectionBtn", true); - if (m_selections.isEmpty()) { - btn->setDefault(true); - btn->setAutoDefault(true); - } - connect(btn, &QPushButton::clicked, - this, &VSelectDialog::selectionChosen); - m_selections.insert(btn, p_selectID); - m_mainLayout->insertWidget(m_selections.size() - 1, btn); -} - -void VSelectDialog::selectionChosen() -{ - QPushButton *btn = dynamic_cast(sender()); - Q_ASSERT(btn); - auto it = m_selections.find(btn); - Q_ASSERT(it != m_selections.end()); - m_choice = *it; - accept(); -} - -int VSelectDialog::getSelection() const -{ - return m_choice; -} diff --git a/src/dialog/vselectdialog.h b/src/dialog/vselectdialog.h deleted file mode 100644 index 93206ab9..00000000 --- a/src/dialog/vselectdialog.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef VSELECTDIALOG_H -#define VSELECTDIALOG_H - -#include -#include - -class QPushButton; -class QVBoxLayout; -class QMouseEvent; - -class VSelectDialog : public QDialog -{ - Q_OBJECT -public: - VSelectDialog(const QString &p_title, QWidget *p_parent = 0); - - void addSelection(const QString &p_selectStr, int p_selectID); - int getSelection() const; - -private slots: - void selectionChosen(); - -private: - void setupUI(const QString &p_title); - - QVBoxLayout *m_mainLayout; - int m_choice; - QMap m_selections; -}; - -#endif // VSELECTDIALOG_H diff --git a/src/dialog/vsettingsdialog.cpp b/src/dialog/vsettingsdialog.cpp deleted file mode 100644 index d6ab3d79..00000000 --- a/src/dialog/vsettingsdialog.cpp +++ /dev/null @@ -1,810 +0,0 @@ -#include "vsettingsdialog.h" -#include -#include -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "vconstants.h" - -extern VConfigManager *g_config; - -VSettingsDialog::VSettingsDialog(QWidget *p_parent) - : QDialog(p_parent) -{ - m_tabList = new QListWidget(this); - m_tabList->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); - - m_tabs = new QStackedLayout(); - - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &VSettingsDialog::saveConfiguration); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - m_btnBox->button(QDialogButtonBox::Ok)->setProperty("SpecialBtn", true); - - QHBoxLayout *tabLayout = new QHBoxLayout(); - tabLayout->addWidget(m_tabList); - tabLayout->addLayout(m_tabs); - tabLayout->setContentsMargins(0, 0, 0, 0); - tabLayout->setSpacing(0); - tabLayout->setStretch(0, 0); - tabLayout->setStretch(1, 5); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(tabLayout); - mainLayout->addWidget(m_btnBox); - setLayout(mainLayout); - - setWindowTitle(tr("Settings")); - - // Add tabs. - addTab(new VGeneralTab(), tr("General")); - addTab(new VReadEditTab(), tr("Read/Edit")); - addTab(new VNoteManagementTab(), tr("Note Management")); - addTab(new VMarkdownTab(), tr("Markdown")); - - m_tabList->setMaximumWidth(m_tabList->sizeHintForColumn(0) + 5); - - connect(m_tabList, &QListWidget::currentItemChanged, - this, [this](QListWidgetItem *p_cur, QListWidgetItem *p_pre) { - Q_UNUSED(p_pre); - Q_ASSERT(p_cur); - int idx = p_cur->data(Qt::UserRole).toInt(); - Q_ASSERT(idx >= 0); - m_tabs->setCurrentWidget(m_tabs->widget(idx)); - }); - - m_tabList->setCurrentRow(0); - - loadConfiguration(); -} - -void VSettingsDialog::addTab(QWidget *p_widget, const QString &p_label) -{ - int idx = m_tabs->addWidget(p_widget); - QListWidgetItem *item = new QListWidgetItem(p_label, m_tabList); - item->setData(Qt::UserRole, idx); -} - -void VSettingsDialog::loadConfiguration() -{ - // General Tab. - { - VGeneralTab *generalTab = dynamic_cast(m_tabs->widget(0)); - Q_ASSERT(generalTab); - if (!generalTab->loadConfiguration()) { - goto err; - } - } - - // Read/Edit Tab. - { - VReadEditTab *readEditTab = dynamic_cast(m_tabs->widget(1)); - Q_ASSERT(readEditTab); - if (!readEditTab->loadConfiguration()) { - goto err; - } - } - - // Note Management Tab. - { - VNoteManagementTab *noteManagementTab = dynamic_cast(m_tabs->widget(2)); - Q_ASSERT(noteManagementTab); - if (!noteManagementTab->loadConfiguration()) { - goto err; - } - } - - // Markdown Tab. - { - VMarkdownTab *markdownTab = dynamic_cast(m_tabs->widget(3)); - Q_ASSERT(markdownTab); - if (!markdownTab->loadConfiguration()) { - goto err; - } - } - - return; -err: - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Fail to load configuration."), "", - QMessageBox::Ok, QMessageBox::Ok, NULL); - QMetaObject::invokeMethod(this, "reject", Qt::QueuedConnection); -} - -void VSettingsDialog::saveConfiguration() -{ - // General Tab. - { - VGeneralTab *generalTab = dynamic_cast(m_tabs->widget(0)); - Q_ASSERT(generalTab); - if (!generalTab->saveConfiguration()) { - goto err; - } - } - - // Read/Edit Tab. - { - VReadEditTab *readEditTab = dynamic_cast(m_tabs->widget(1)); - Q_ASSERT(readEditTab); - if (!readEditTab->saveConfiguration()) { - goto err; - } - } - - // Note Management Tab. - { - VNoteManagementTab *noteManagementTab = dynamic_cast(m_tabs->widget(2)); - Q_ASSERT(noteManagementTab); - if (!noteManagementTab->saveConfiguration()) { - goto err; - } - } - - // Markdown Tab. - { - VMarkdownTab *markdownTab = dynamic_cast(m_tabs->widget(3)); - Q_ASSERT(markdownTab); - if (!markdownTab->saveConfiguration()) { - goto err; - } - } - - accept(); - return; -err: - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Fail to save configuration. Please try it again."), "", - QMessageBox::Ok, QMessageBox::Ok, NULL); -} - -const QVector VGeneralTab::c_availableLangs = { "System", "English", "Chinese" }; - -VGeneralTab::VGeneralTab(QWidget *p_parent) - : QWidget(p_parent) -{ - // Language combo. - m_langCombo = VUtils::getComboBox(this); - m_langCombo->setToolTip(tr("Choose the language of VNote interface")); - m_langCombo->addItem(tr("System"), "System"); - auto langs = VUtils::getAvailableLanguages(); - for (auto const &lang : langs) { - m_langCombo->addItem(lang.second, lang.first); - } - - // System tray checkbox. - m_systemTray = new QCheckBox(tr("System tray"), this); - m_systemTray->setToolTip(tr("Minimized to the system tray after closing VNote" - " (not supported in macOS)")); -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - // Do not support minimized to tray on macOS. - m_systemTray->setEnabled(false); -#endif - - // Startup pages. - QLayout *startupLayout = setupStartupPagesLayout(); - - QFormLayout *optionLayout = new QFormLayout(); - optionLayout->addRow(tr("Language:"), m_langCombo); - optionLayout->addRow(m_systemTray); - optionLayout->addRow(tr("Startup pages:"), startupLayout); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(optionLayout); - - setLayout(mainLayout); -} - -QLayout *VGeneralTab::setupStartupPagesLayout() -{ - m_startupPageTypeCombo = VUtils::getComboBox(this); - m_startupPageTypeCombo->setToolTip(tr("Restore tabs or open specific notes on startup")); - m_startupPageTypeCombo->addItem(tr("None"), (int)StartupPageType::None); - m_startupPageTypeCombo->addItem(tr("Continue where you left off"), (int)StartupPageType::ContinueLeftOff); - m_startupPageTypeCombo->addItem(tr("Open specific pages"), (int)StartupPageType::SpecificPages); - connect(m_startupPageTypeCombo, static_cast(&QComboBox::activated), - this, [this](int p_index) { - int type = m_startupPageTypeCombo->itemData(p_index).toInt(); - bool pagesEditVisible = type == (int)StartupPageType::SpecificPages; - m_startupPagesEdit->setVisible(pagesEditVisible); - m_startupPagesAddBtn->setVisible(pagesEditVisible); - }); - - m_startupPagesEdit = new QPlainTextEdit(this); - m_startupPagesEdit->setProperty("LineEdit", true); - m_startupPagesEdit->setToolTip(tr("Absolute path of the notes to open on startup (one note per line)")); - - m_startupPagesAddBtn = new QPushButton(tr("Browse"), this); - m_startupPagesAddBtn->setToolTip(tr("Select files to add as startup pages")); - connect(m_startupPagesAddBtn, &QPushButton::clicked, - this, [this]() { - static QString lastPath = QDir::homePath(); - QStringList files = QFileDialog::getOpenFileNames(this, - tr("Select Files As Startup Pages"), - lastPath); - if (files.isEmpty()) { - return; - } - - // Update lastPath - lastPath = QFileInfo(files[0]).path(); - - m_startupPagesEdit->appendPlainText(files.join("\n")); - }); - - QHBoxLayout *startupPagesBtnLayout = new QHBoxLayout(); - startupPagesBtnLayout->addStretch(); - startupPagesBtnLayout->addWidget(m_startupPagesAddBtn); - - QVBoxLayout *startupPagesLayout = new QVBoxLayout(); - startupPagesLayout->addWidget(m_startupPagesEdit); - startupPagesLayout->addLayout(startupPagesBtnLayout); - - QVBoxLayout *startupLayout = new QVBoxLayout(); - startupLayout->addWidget(m_startupPageTypeCombo); - startupLayout->addLayout(startupPagesLayout); - - m_startupPagesEdit->hide(); - m_startupPagesAddBtn->hide(); - - return startupLayout; -} - -bool VGeneralTab::loadConfiguration() -{ - if (!loadLanguage()) { - return false; - } - - if (!loadSystemTray()) { - return false; - } - - if (!loadStartupPageType()) { - return false; - } - - return true; -} - -bool VGeneralTab::saveConfiguration() -{ - if (!saveLanguage()) { - return false; - } - - if (!saveSystemTray()) { - return false; - } - - if (!saveStartupPageType()) { - return false; - } - - return true; -} - -bool VGeneralTab::loadLanguage() -{ - QString lang = g_config->getLanguage(); - if (lang.isNull()) { - return false; - } else if (lang == "System") { - m_langCombo->setCurrentIndex(0); - return true; - } - bool found = false; - // lang is the value, not name. - for (int i = 0; i < m_langCombo->count(); ++i) { - if (m_langCombo->itemData(i).toString() == lang) { - found = true; - m_langCombo->setCurrentIndex(i); - break; - } - } - if (!found) { - qWarning() << "invalid language configuration (using default value)"; - m_langCombo->setCurrentIndex(0); - } - return true; -} - -bool VGeneralTab::saveLanguage() -{ - QString curLang = m_langCombo->currentData().toString(); - g_config->setLanguage(curLang); - return true; -} - -bool VGeneralTab::loadSystemTray() -{ - m_systemTray->setChecked(g_config->getMinimizeToStystemTray() != 0); - return true; -} - -bool VGeneralTab::saveSystemTray() -{ - if (m_systemTray->isEnabled()) { - g_config->setMinimizeToSystemTray(m_systemTray->isChecked() ? 1 : 0); - } - - return true; -} - -bool VGeneralTab::loadStartupPageType() -{ - StartupPageType type = g_config->getStartupPageType(); - bool found = false; - for (int i = 0; i < m_startupPageTypeCombo->count(); ++i) { - if (m_startupPageTypeCombo->itemData(i).toInt() == (int)type) { - found = true; - m_startupPageTypeCombo->setCurrentIndex(i); - } - } - - Q_ASSERT(found); - - const QStringList &pages = g_config->getStartupPages(); - m_startupPagesEdit->setPlainText(pages.join("\n")); - - bool pagesEditVisible = type == StartupPageType::SpecificPages; - m_startupPagesEdit->setVisible(pagesEditVisible); - m_startupPagesAddBtn->setVisible(pagesEditVisible); - - return true; -} - -bool VGeneralTab::saveStartupPageType() -{ - StartupPageType type = (StartupPageType)m_startupPageTypeCombo->currentData().toInt(); - g_config->setStartupPageType(type); - - if (type == StartupPageType::SpecificPages) { - QStringList pages = m_startupPagesEdit->toPlainText().split("\n"); - g_config->setStartupPages(pages); - } - - return true; -} - -VReadEditTab::VReadEditTab(QWidget *p_parent) - : QWidget(p_parent) -{ - m_readBox = new QGroupBox(tr("Read Mode (For Markdown Only)")); - m_editBox = new QGroupBox(tr("Edit Mode")); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(m_readBox); - mainLayout->addWidget(m_editBox); - setLayout(mainLayout); -} - -bool VReadEditTab::loadConfiguration() -{ - return true; -} - -bool VReadEditTab::saveConfiguration() -{ - return true; -} - -VNoteManagementTab::VNoteManagementTab(QWidget *p_parent) - : QWidget(p_parent) -{ - m_noteBox = new QGroupBox(tr("Notes")); - m_externalBox = new QGroupBox(tr("External Files")); - - // Note. - // Image folder. - m_customImageFolder = new QCheckBox(tr("Custom image folder"), this); - m_customImageFolder->setToolTip(tr("Set the global name of the image folder to hold images " - "of notes (restart VNote to make it work)")); - connect(m_customImageFolder, &QCheckBox::stateChanged, - this, &VNoteManagementTab::customImageFolderChanged); - - m_imageFolderEdit = new QLineEdit(this); - m_imageFolderEdit->setPlaceholderText(tr("Name of the image folder")); - m_imageFolderEdit->setToolTip(m_customImageFolder->toolTip()); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), this); - m_imageFolderEdit->setValidator(validator); - - QHBoxLayout *imageFolderLayout = new QHBoxLayout(); - imageFolderLayout->addWidget(m_customImageFolder); - imageFolderLayout->addWidget(m_imageFolderEdit); - - // Attachment folder. - m_customAttachmentFolder = new QCheckBox(tr("Custom attachment folder"), this); - m_customAttachmentFolder->setToolTip(tr("Set the global name of the attachment folder to hold attachments " - "of notes (restart VNote to make it work)")); - connect(m_customAttachmentFolder, &QCheckBox::stateChanged, - this, &VNoteManagementTab::customAttachmentFolderChanged); - - m_attachmentFolderEdit = new QLineEdit(this); - m_attachmentFolderEdit->setPlaceholderText(tr("Name of the attachment folder")); - m_attachmentFolderEdit->setToolTip(m_customAttachmentFolder->toolTip()); - validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), this); - m_attachmentFolderEdit->setValidator(validator); - - QHBoxLayout *attachmentFolderLayout = new QHBoxLayout(); - attachmentFolderLayout->addWidget(m_customAttachmentFolder); - attachmentFolderLayout->addWidget(m_attachmentFolderEdit); - - QFormLayout *noteLayout = new QFormLayout(); - noteLayout->addRow(imageFolderLayout); - noteLayout->addRow(attachmentFolderLayout); - m_noteBox->setLayout(noteLayout); - - // External File. - // Image folder. - m_customImageFolderExt = new QCheckBox(tr("Custom image folder"), this); - m_customImageFolderExt->setToolTip(tr("Set the path of the global image folder to hold images " - "of external files (restart VNote to make it work).\nYou " - "could use both absolute or relative path here. If " - "absolute path is used, VNote will not manage\nthose images, " - "so you need to clean up unused images manually.")); - connect(m_customImageFolderExt, &QCheckBox::stateChanged, - this, &VNoteManagementTab::customImageFolderExtChanged); - - m_imageFolderEditExt = new QLineEdit(this); - m_imageFolderEditExt->setToolTip(m_customImageFolderExt->toolTip()); - m_imageFolderEditExt->setPlaceholderText(tr("Name of the image folder")); - - QHBoxLayout *imageFolderExtLayout = new QHBoxLayout(); - imageFolderExtLayout->addWidget(m_customImageFolderExt); - imageFolderExtLayout->addWidget(m_imageFolderEditExt); - - QFormLayout *externalLayout = new QFormLayout(); - externalLayout->addRow(imageFolderExtLayout); - m_externalBox->setLayout(externalLayout); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(m_noteBox); - mainLayout->addWidget(m_externalBox); - - setLayout(mainLayout); -} - -bool VNoteManagementTab::loadConfiguration() -{ - if (!loadImageFolder()) { - return false; - } - - if (!loadAttachmentFolder()) { - return false; - } - - if (!loadImageFolderExt()) { - return false; - } - - return true; -} - -bool VNoteManagementTab::saveConfiguration() -{ - if (!saveImageFolder()) { - return false; - } - - if (!saveAttachmentFolder()) { - return false; - } - - if (!saveImageFolderExt()) { - return false; - } - - return true; -} - -bool VNoteManagementTab::loadImageFolder() -{ - bool isCustom = g_config->isCustomImageFolder(); - - m_customImageFolder->setChecked(isCustom); - m_imageFolderEdit->setText(g_config->getImageFolder()); - m_imageFolderEdit->setEnabled(isCustom); - - return true; -} - -bool VNoteManagementTab::saveImageFolder() -{ - if (m_customImageFolder->isChecked()) { - g_config->setImageFolder(m_imageFolderEdit->text()); - } else { - g_config->setImageFolder(""); - } - - return true; -} - -void VNoteManagementTab::customImageFolderChanged(int p_state) -{ - if (p_state == Qt::Checked) { - m_imageFolderEdit->setEnabled(true); - m_imageFolderEdit->selectAll(); - m_imageFolderEdit->setFocus(); - } else { - m_imageFolderEdit->setEnabled(false); - } -} - -bool VNoteManagementTab::loadAttachmentFolder() -{ - bool isCustom = g_config->isCustomAttachmentFolder(); - - m_customAttachmentFolder->setChecked(isCustom); - m_attachmentFolderEdit->setText(g_config->getAttachmentFolder()); - m_attachmentFolderEdit->setEnabled(isCustom); - - return true; -} - -bool VNoteManagementTab::saveAttachmentFolder() -{ - if (m_customAttachmentFolder->isChecked()) { - g_config->setAttachmentFolder(m_attachmentFolderEdit->text()); - } else { - g_config->setAttachmentFolder(""); - } - - return true; -} - -void VNoteManagementTab::customAttachmentFolderChanged(int p_state) -{ - if (p_state == Qt::Checked) { - m_attachmentFolderEdit->setEnabled(true); - m_attachmentFolderEdit->selectAll(); - m_attachmentFolderEdit->setFocus(); - } else { - m_attachmentFolderEdit->setEnabled(false); - } -} - -bool VNoteManagementTab::loadImageFolderExt() -{ - bool isCustom = g_config->isCustomImageFolderExt(); - - m_customImageFolderExt->setChecked(isCustom); - m_imageFolderEditExt->setText(g_config->getImageFolderExt()); - m_imageFolderEditExt->setEnabled(isCustom); - - return true; -} - -bool VNoteManagementTab::saveImageFolderExt() -{ - if (m_customImageFolderExt->isChecked()) { - g_config->setImageFolderExt(m_imageFolderEditExt->text()); - } else { - g_config->setImageFolderExt(""); - } - - return true; -} - -void VNoteManagementTab::customImageFolderExtChanged(int p_state) -{ - if (p_state == Qt::Checked) { - m_imageFolderEditExt->setEnabled(true); - m_imageFolderEditExt->selectAll(); - m_imageFolderEditExt->setFocus(); - } else { - m_imageFolderEditExt->setEnabled(false); - } -} - -VMarkdownTab::VMarkdownTab(QWidget *p_parent) - : QWidget(p_parent) -{ - // Default note open mode. - m_openModeCombo = VUtils::getComboBox(); - m_openModeCombo->setToolTip(tr("Default mode to open a note")); - m_openModeCombo->addItem(tr("Read Mode"), (int)OpenFileMode::Read); - m_openModeCombo->addItem(tr("Edit Mode"), (int)OpenFileMode::Edit); - - // Heading sequence. - m_headingSequenceTypeCombo = VUtils::getComboBox(); - m_headingSequenceTypeCombo->setToolTip(tr("Enable auto sequence for all headings (in the form like 1.2.3.4.)")); - m_headingSequenceTypeCombo->addItem(tr("Disabled"), (int)HeadingSequenceType::Disabled); - m_headingSequenceTypeCombo->addItem(tr("Enabled"), (int)HeadingSequenceType::Enabled); - m_headingSequenceTypeCombo->addItem(tr("Enabled for notes only"), (int)HeadingSequenceType::EnabledNoteOnly); - - m_headingSequenceLevelCombo = VUtils::getComboBox(); - m_headingSequenceLevelCombo->setToolTip(tr("Base level to start heading sequence")); - m_headingSequenceLevelCombo->addItem(tr("1"), 1); - m_headingSequenceLevelCombo->addItem(tr("2"), 2); - m_headingSequenceLevelCombo->addItem(tr("3"), 3); - m_headingSequenceLevelCombo->addItem(tr("4"), 4); - m_headingSequenceLevelCombo->addItem(tr("5"), 5); - m_headingSequenceLevelCombo->addItem(tr("6"), 6); - m_headingSequenceLevelCombo->setEnabled(false); - - connect(m_headingSequenceTypeCombo, static_cast(&QComboBox::activated), - this, [this](int p_index){ - if (p_index > -1) { - HeadingSequenceType type = (HeadingSequenceType)m_headingSequenceTypeCombo->itemData(p_index).toInt(); - m_headingSequenceLevelCombo->setEnabled(type != HeadingSequenceType::Disabled); - } - }); - - QHBoxLayout *headingSequenceLayout = new QHBoxLayout(); - headingSequenceLayout->addWidget(m_headingSequenceTypeCombo); - headingSequenceLayout->addWidget(m_headingSequenceLevelCombo); - - // Web Zoom Factor. - m_customWebZoom = new QCheckBox(tr("Custom Web zoom factor"), this); - m_customWebZoom->setToolTip(tr("Set the zoom factor of the Web page when reading")); - m_webZoomFactorSpin = new QDoubleSpinBox(this); - m_webZoomFactorSpin->setMaximum(c_webZoomFactorMax); - m_webZoomFactorSpin->setMinimum(c_webZoomFactorMin); - m_webZoomFactorSpin->setSingleStep(0.25); - connect(m_customWebZoom, &QCheckBox::stateChanged, - this, [this](int p_state){ - this->m_webZoomFactorSpin->setEnabled(p_state == Qt::Checked); - }); - QHBoxLayout *zoomFactorLayout = new QHBoxLayout(); - zoomFactorLayout->addWidget(m_customWebZoom); - zoomFactorLayout->addWidget(m_webZoomFactorSpin); - - // Color column. - m_colorColumnEdit = new QLineEdit(); - m_colorColumnEdit->setToolTip(tr("Specify the screen column in fenced code block " - "which will be highlighted")); - QValidator *validator = new QRegExpValidator(QRegExp("\\d+"), this); - m_colorColumnEdit->setValidator(validator); - - QLabel *colorColumnLabel = new QLabel(tr("Color column:")); - colorColumnLabel->setToolTip(m_colorColumnEdit->toolTip()); - - QFormLayout *mainLayout = new QFormLayout(); - mainLayout->addRow(tr("Note open mode:"), m_openModeCombo); - mainLayout->addRow(tr("Heading sequence:"), headingSequenceLayout); - mainLayout->addRow(zoomFactorLayout); - mainLayout->addRow(colorColumnLabel, m_colorColumnEdit); - - setLayout(mainLayout); -} - -bool VMarkdownTab::loadConfiguration() -{ - if (!loadOpenMode()) { - return false; - } - - if (!loadHeadingSequence()) { - return false; - } - - if (!loadWebZoomFactor()) { - return false; - } - - if (!loadColorColumn()) { - return false; - } - - return true; -} - -bool VMarkdownTab::saveConfiguration() -{ - if (!saveOpenMode()) { - return false; - } - - if (!saveHeadingSequence()) { - return false; - } - - if (!saveWebZoomFactor()) { - return false; - } - - if (!saveColorColumn()) { - return false; - } - - return true; -} - -bool VMarkdownTab::loadOpenMode() -{ - int mode = (int)g_config->getNoteOpenMode(); - bool found = false; - for (int i = 0; i < m_openModeCombo->count(); ++i) { - if (m_openModeCombo->itemData(i).toInt() == mode) { - m_openModeCombo->setCurrentIndex(i); - found = true; - break; - } - } - - Q_ASSERT(found); - return true; -} - -bool VMarkdownTab::saveOpenMode() -{ - int mode = m_openModeCombo->currentData().toInt(); - g_config->setNoteOpenMode((OpenFileMode)mode); - return true; -} - -bool VMarkdownTab::loadHeadingSequence() -{ - HeadingSequenceType type = g_config->getHeadingSequenceType(); - int level = g_config->getHeadingSequenceBaseLevel(); - if (level < 1 || level > 6) { - level = 1; - } - - int idx = m_headingSequenceTypeCombo->findData((int)type); - Q_ASSERT(idx > -1); - m_headingSequenceTypeCombo->setCurrentIndex(idx); - m_headingSequenceLevelCombo->setCurrentIndex(level - 1); - m_headingSequenceLevelCombo->setEnabled(type != HeadingSequenceType::Disabled); - - return true; -} - -bool VMarkdownTab::saveHeadingSequence() -{ - QVariant typeData = m_headingSequenceTypeCombo->currentData(); - Q_ASSERT(typeData.isValid()); - g_config->setHeadingSequenceType((HeadingSequenceType)typeData.toInt()); - g_config->setHeadingSequenceBaseLevel(m_headingSequenceLevelCombo->currentData().toInt()); - - return true; -} - -bool VMarkdownTab::loadWebZoomFactor() -{ - qreal factor = g_config->getWebZoomFactor(); - bool customFactor = g_config->isCustomWebZoomFactor(); - if (customFactor) { - if (factor < c_webZoomFactorMin || factor > c_webZoomFactorMax) { - factor = 1; - } - m_customWebZoom->setChecked(true); - m_webZoomFactorSpin->setValue(factor); - } else { - m_customWebZoom->setChecked(false); - m_webZoomFactorSpin->setValue(factor); - m_webZoomFactorSpin->setEnabled(false); - } - - return true; -} - -bool VMarkdownTab::saveWebZoomFactor() -{ - if (m_customWebZoom->isChecked()) { - g_config->setWebZoomFactor(m_webZoomFactorSpin->value()); - } else { - g_config->setWebZoomFactor(-1); - } - - return true; -} - -bool VMarkdownTab::loadColorColumn() -{ - int colorColumn = g_config->getColorColumn(); - m_colorColumnEdit->setText(QString::number(colorColumn <= 0 ? 0 : colorColumn)); - return true; -} - -bool VMarkdownTab::saveColorColumn() -{ - bool ok = false; - int colorColumn = m_colorColumnEdit->text().toInt(&ok); - if (ok && colorColumn >= 0) { - g_config->setColorColumn(colorColumn); - } - - return true; -} - diff --git a/src/dialog/vsettingsdialog.h b/src/dialog/vsettingsdialog.h deleted file mode 100644 index 2406134f..00000000 --- a/src/dialog/vsettingsdialog.h +++ /dev/null @@ -1,163 +0,0 @@ -#ifndef VSETTINGSDIALOG_H -#define VSETTINGSDIALOG_H - -#include -#include -#include - -class QDialogButtonBox; -class QComboBox; -class QGroupBox; -class QDoubleSpinBox; -class QCheckBox; -class QLineEdit; -class QStackedLayout; -class QListWidget; -class QPlainTextEdit; -class QVBoxLayout; - -class VGeneralTab : public QWidget -{ - Q_OBJECT -public: - explicit VGeneralTab(QWidget *p_parent = 0); - bool loadConfiguration(); - bool saveConfiguration(); - -private: - QLayout *setupStartupPagesLayout(); - - bool loadLanguage(); - bool saveLanguage(); - - bool loadSystemTray(); - bool saveSystemTray(); - - bool loadStartupPageType(); - bool saveStartupPageType(); - - // Language - QComboBox *m_langCombo; - - // System tray - QCheckBox *m_systemTray; - - // Startup page type. - QComboBox *m_startupPageTypeCombo; - - // Startup pages. - QPlainTextEdit *m_startupPagesEdit; - - // Startup pages add files button. - QPushButton *m_startupPagesAddBtn; - - static const QVector c_availableLangs; -}; - -class VReadEditTab : public QWidget -{ - Q_OBJECT -public: - explicit VReadEditTab(QWidget *p_parent = 0); - bool loadConfiguration(); - bool saveConfiguration(); - - QGroupBox *m_readBox; - QGroupBox *m_editBox; -}; - -class VNoteManagementTab : public QWidget -{ - Q_OBJECT -public: - explicit VNoteManagementTab(QWidget *p_parent = 0); - bool loadConfiguration(); - bool saveConfiguration(); - - QGroupBox *m_noteBox; - QGroupBox *m_externalBox; - - // Image folder. - QCheckBox *m_customImageFolder; - QLineEdit *m_imageFolderEdit; - - // Image folder of External File. - QCheckBox *m_customImageFolderExt; - QLineEdit *m_imageFolderEditExt; - - // Attachment folder. - QCheckBox *m_customAttachmentFolder; - QLineEdit *m_attachmentFolderEdit; - -private slots: - void customImageFolderChanged(int p_state); - void customImageFolderExtChanged(int p_state); - void customAttachmentFolderChanged(int p_state); - -private: - bool loadImageFolder(); - bool saveImageFolder(); - - bool loadImageFolderExt(); - bool saveImageFolderExt(); - - bool loadAttachmentFolder(); - bool saveAttachmentFolder(); -}; - -class VMarkdownTab : public QWidget -{ - Q_OBJECT -public: - explicit VMarkdownTab(QWidget *p_parent = 0); - bool loadConfiguration(); - bool saveConfiguration(); - - // Default note open mode for markdown. - QComboBox *m_openModeCombo; - - // Whether enable heading sequence. - QComboBox *m_headingSequenceTypeCombo; - QComboBox *m_headingSequenceLevelCombo; - - // Web zoom factor. - QCheckBox *m_customWebZoom; - QDoubleSpinBox *m_webZoomFactorSpin; - - // Color column in code block. - QLineEdit *m_colorColumnEdit; - -private: - bool loadOpenMode(); - bool saveOpenMode(); - - bool loadHeadingSequence(); - bool saveHeadingSequence(); - - bool loadWebZoomFactor(); - bool saveWebZoomFactor(); - - bool loadColorColumn(); - bool saveColorColumn(); -}; - -class VSettingsDialog : public QDialog -{ - Q_OBJECT -public: - explicit VSettingsDialog(QWidget *p_parent = 0); - -private slots: - void saveConfiguration(); - -private: - void loadConfiguration(); - - void addTab(QWidget *p_widget, const QString &p_label); - - QStackedLayout *m_tabs; - QListWidget *m_tabList; - QDialogButtonBox *m_btnBox; -}; - -#endif // VSETTINGSDIALOG_H diff --git a/src/dialog/vsortdialog.cpp b/src/dialog/vsortdialog.cpp deleted file mode 100644 index 74f37790..00000000 --- a/src/dialog/vsortdialog.cpp +++ /dev/null @@ -1,275 +0,0 @@ -#include "vsortdialog.h" - -#include - -void VTreeWidget::dropEvent(QDropEvent *p_event) -{ - QList dragItems = selectedItems(); - - int first = -1, last = -1; - QTreeWidgetItem *firstItem = NULL; - for (int i = 0; i < dragItems.size(); ++i) { - int row = indexFromItem(dragItems[i]).row(); - if (row > last) { - last = row; - } - - if (first == -1 || row < first) { - first = row; - firstItem = dragItems[i]; - } - } - - Q_ASSERT(firstItem); - - QTreeWidget::dropEvent(p_event); - - int target = indexFromItem(firstItem).row(); - emit rowsMoved(first, last, target); -} - - -VSortDialog::VSortDialog(const QString &p_title, - const QString &p_info, - QWidget *p_parent) - : QDialog(p_parent) -{ - setupUI(p_title, p_info); -} - -void VSortDialog::setupUI(const QString &p_title, const QString &p_info) -{ - QLabel *infoLabel = NULL; - if (!p_info.isEmpty()) { - infoLabel = new QLabel(p_info); - infoLabel->setWordWrap(true); - } - - m_treeWidget = new VTreeWidget(); - m_treeWidget->setRootIsDecorated(false); - m_treeWidget->setSelectionMode(QAbstractItemView::ContiguousSelection); - m_treeWidget->setDragDropMode(QAbstractItemView::InternalMove); - connect(m_treeWidget, &VTreeWidget::rowsMoved, - this, [this](int p_first, int p_last, int p_row) { - Q_UNUSED(p_first); - Q_UNUSED(p_last); - QTreeWidgetItem *item = m_treeWidget->topLevelItem(p_row); - if (item) { - m_treeWidget->setCurrentItem(item); - - // Select all items back. - int cnt = p_last - p_first + 1; - for (int i = 0; i < cnt; ++i) { - QTreeWidgetItem *it = m_treeWidget->topLevelItem(p_row + i); - if (it) { - it->setSelected(true); - } - } - } - }); - - // Buttons for top/up/down/bottom. - m_topBtn = new QPushButton(tr("&Top")); - m_topBtn->setToolTip(tr("Move selected items to top")); - connect(m_topBtn, &QPushButton::clicked, - this, [this]() { - this->handleMoveOperation(MoveOperation::Top); - }); - - m_upBtn = new QPushButton(tr("&Up")); - m_upBtn->setToolTip(tr("Move selected items up")); - connect(m_upBtn, &QPushButton::clicked, - this, [this]() { - this->handleMoveOperation(MoveOperation::Up); - }); - - m_downBtn = new QPushButton(tr("&Down")); - m_downBtn->setToolTip(tr("Move selected items down")); - connect(m_downBtn, &QPushButton::clicked, - this, [this]() { - this->handleMoveOperation(MoveOperation::Down); - }); - - m_bottomBtn = new QPushButton(tr("&Bottom")); - m_bottomBtn->setToolTip(tr("Move selected items to bottom")); - connect(m_bottomBtn, &QPushButton::clicked, - this, [this]() { - this->handleMoveOperation(MoveOperation::Bottom); - }); - - QVBoxLayout *btnLayout = new QVBoxLayout; - btnLayout->addWidget(m_topBtn); - btnLayout->addWidget(m_upBtn); - btnLayout->addWidget(m_downBtn); - btnLayout->addWidget(m_bottomBtn); - btnLayout->addStretch(); - - QHBoxLayout *midLayout = new QHBoxLayout; - midLayout->addWidget(m_treeWidget); - midLayout->addLayout(btnLayout); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - m_btnBox->button(QDialogButtonBox::Ok)->setProperty("SpecialBtn", true); - - QVBoxLayout *mainLayout = new QVBoxLayout; - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - - mainLayout->addLayout(midLayout); - mainLayout->addWidget(m_btnBox); - - setLayout(mainLayout); - setWindowTitle(p_title); -} - -void VSortDialog::treeUpdated() -{ - int cols = m_treeWidget->columnCount(); - for (int i = 0; i < cols; ++i) { - m_treeWidget->resizeColumnToContents(i); - } - - QHeaderView *header = m_treeWidget->header(); - if (header) { - header->setStretchLastSection(true); - } - - // We just need single level. - int cnt = m_treeWidget->topLevelItemCount(); - for (int i = 0; i < cnt; ++i) { - QTreeWidgetItem *item = m_treeWidget->topLevelItem(i); - item->setFlags(item->flags() & ~Qt::ItemIsDropEnabled); - } -} - -void VSortDialog::handleMoveOperation(MoveOperation p_op) -{ - const QList selectedItems = m_treeWidget->selectedItems(); - if (selectedItems.isEmpty()) { - return; - } - - int first = m_treeWidget->topLevelItemCount(); - int last = -1; - for (auto const & it : selectedItems) { - int idx = m_treeWidget->indexOfTopLevelItem(it); - Q_ASSERT(idx > -1); - if (idx < first) { - first = idx; - } - - if (idx > last) { - last = idx; - } - } - - Q_ASSERT(first <= last && (last - first + 1) == selectedItems.size()); - QTreeWidgetItem *firstItem = NULL; - - switch (p_op) { - case MoveOperation::Top: - if (first == 0) { - break; - } - - m_treeWidget->clearSelection(); - - // Insert item[last] to index 0 repeatedly. - for (int i = last - first; i >= 0; --i) { - QTreeWidgetItem *item = m_treeWidget->takeTopLevelItem(last); - Q_ASSERT(item); - m_treeWidget->insertTopLevelItem(0, item); - item->setSelected(true); - } - - firstItem = m_treeWidget->topLevelItem(0); - - break; - - case MoveOperation::Up: - if (first == 0) { - break; - } - - m_treeWidget->clearSelection(); - - // Insert item[last] to index (first -1) repeatedly. - for (int i = last - first; i >= 0; --i) { - QTreeWidgetItem *item = m_treeWidget->takeTopLevelItem(last); - Q_ASSERT(item); - m_treeWidget->insertTopLevelItem(first - 1, item); - item->setSelected(true); - } - - firstItem = m_treeWidget->topLevelItem(first - 1); - - break; - - case MoveOperation::Down: - if (last == m_treeWidget->topLevelItemCount() - 1) { - break; - } - - m_treeWidget->clearSelection(); - - // Insert item[first] to index (last) repeatedly. - for (int i = last - first; i >= 0; --i) { - QTreeWidgetItem *item = m_treeWidget->takeTopLevelItem(first); - Q_ASSERT(item); - m_treeWidget->insertTopLevelItem(last + 1, item); - item->setSelected(true); - - if (!firstItem) { - firstItem = item; - } - } - - break; - - case MoveOperation::Bottom: - if (last == m_treeWidget->topLevelItemCount() - 1) { - break; - } - - m_treeWidget->clearSelection(); - - // Insert item[first] to the last of the tree repeatedly. - for (int i = last - first; i >= 0; --i) { - QTreeWidgetItem *item = m_treeWidget->takeTopLevelItem(first); - Q_ASSERT(item); - m_treeWidget->addTopLevelItem(item); - item->setSelected(true); - - if (!firstItem) { - firstItem = item; - } - } - - break; - - default: - return; - } - - if (firstItem) { - m_treeWidget->setCurrentItem(firstItem); - m_treeWidget->scrollToItem(firstItem); - } -} - -QVector VSortDialog::getSortedData() const -{ - int cnt = m_treeWidget->topLevelItemCount(); - QVector data(cnt); - for (int i = 0; i < cnt; ++i) { - QTreeWidgetItem *item = m_treeWidget->topLevelItem(i); - Q_ASSERT(item); - data[i] = item->data(0, Qt::UserRole); - } - - return data; -} diff --git a/src/dialog/vsortdialog.h b/src/dialog/vsortdialog.h deleted file mode 100644 index 213a1df7..00000000 --- a/src/dialog/vsortdialog.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef VSORTDIALOG_H -#define VSORTDIALOG_H - -#include -#include -#include - -class QPushButton; -class QDialogButtonBox; -class QTreeWidget; -class QDropEvent; - -// QTreeWidget won't emit the rowsMoved() signal after drag-and-drop. -// VTreeWidget will emit rowsMoved() signal. -class VTreeWidget : public QTreeWidget -{ - Q_OBJECT -public: - explicit VTreeWidget(QWidget *p_parent = 0) - : QTreeWidget(p_parent) - { - setAttribute(Qt::WA_MacShowFocusRect, false); - } - -protected: - void dropEvent(QDropEvent *p_event) Q_DECL_OVERRIDE; - -signals: - // Rows [@p_first, @p_last] were moved to @p_row. - void rowsMoved(int p_first, int p_last, int p_row); - -}; - -class VSortDialog : public QDialog -{ - Q_OBJECT -public: - VSortDialog(const QString &p_title, - const QString &p_info, - QWidget *p_parent = 0); - - QTreeWidget *getTreeWidget() const; - - // Called after updating the m_treeWidget. - void treeUpdated(); - - // Get user data of column 0 from sorted items. - QVector getSortedData() const; - -private: - enum MoveOperation { Top, Up, Down, Bottom }; - -private slots: - void handleMoveOperation(MoveOperation p_op); - -private: - void setupUI(const QString &p_title, const QString &p_info); - - VTreeWidget *m_treeWidget; - QPushButton *m_topBtn; - QPushButton *m_upBtn; - QPushButton *m_downBtn; - QPushButton *m_bottomBtn; - QDialogButtonBox *m_btnBox; -}; - -inline QTreeWidget *VSortDialog::getTreeWidget() const -{ - return m_treeWidget; -} - -#endif // VSORTDIALOG_H diff --git a/src/dialog/vupdater.cpp b/src/dialog/vupdater.cpp deleted file mode 100644 index 1518f3b8..00000000 --- a/src/dialog/vupdater.cpp +++ /dev/null @@ -1,172 +0,0 @@ -#include "vupdater.h" - -#include -#include -#include -#include - -#include "vconfigmanager.h" -#include "vdownloader.h" - -extern VConfigManager *g_config; - -VUpdater::VUpdater(QWidget *p_parent) - : QDialog(p_parent) -{ - setupUI(); -} - -void VUpdater::setupUI() -{ - QImage img(":/resources/icons/vnote_update.svg"); - QSize imgSize(128, 128); - QLabel *imgLabel = new QLabel(); - imgLabel->setPixmap(QPixmap::fromImage(img.scaled(imgSize))); - - m_versionLabel = new QLabel(tr("Current Version: v%1") - .arg(g_config->c_version)); - - m_proLabel = new QLabel(tr("Checking for updates...")); - m_proLabel->setOpenExternalLinks(true); - m_proBar = new QProgressBar(); - m_proBar->setTextVisible(false); - - m_descriptionTb = new QTextBrowser(); - - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok); - m_btnBox->button(QDialogButtonBox::Ok)->setProperty("SpecialBtn", true); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - - QVBoxLayout *verLayout = new QVBoxLayout(); - verLayout->addStretch(); - verLayout->addWidget(m_versionLabel); - verLayout->addStretch(); - verLayout->addWidget(m_proLabel); - verLayout->addWidget(m_proBar); - - QHBoxLayout *topLayout = new QHBoxLayout(); - topLayout->addWidget(imgLabel); - topLayout->addLayout(verLayout); - - QVBoxLayout *mainLayout = new QVBoxLayout(this); - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_descriptionTb, 1); - mainLayout->addWidget(m_btnBox); - - m_proLabel->hide(); - m_proBar->hide(); - m_descriptionTb->hide(); - - setLayout(mainLayout); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setWindowTitle(tr("VNote Update")); -} - -void VUpdater::showEvent(QShowEvent *p_event) -{ - Q_UNUSED(p_event); - QDialog::showEvent(p_event); - - QTimer *timer = new QTimer(this); - timer->setSingleShot(true); - timer->setInterval(1000); - connect(timer, &QTimer::timeout, - this, [this]() { - this->checkUpdates(); - }); - - timer->start(); -} - -void VUpdater::checkUpdates() -{ - // Change UI. - m_proLabel->setText(tr("Checking for updates...")); - m_proLabel->show(); - - m_proBar->setEnabled(true); - m_proBar->setMinimum(0); - m_proBar->setMaximum(100); - m_proBar->reset(); - m_proBar->show(); - - QString url("https://api.github.com/repos/tamlok/vnote/releases/latest"); - VDownloader *downloader = new VDownloader(this); - connect(downloader, &VDownloader::downloadFinished, - this, &VUpdater::parseResult); - downloader->download(url); - - m_proBar->setValue(20); -} - -// Return if @p_latestVersion is newer than p_curVersion. -// They are both in format xx.xx.xx.xx -bool isNewerVersion(const QString &p_curVersion, const QString &p_latestVersion) -{ - QStringList curList = p_curVersion.split('.', QString::SkipEmptyParts); - QStringList latestList = p_latestVersion.split('.', QString::SkipEmptyParts); - - int i = 0; - for (; i < curList.size() && i < latestList.size(); ++i) { - int a = curList[i].toInt(); - int b = latestList[i].toInt(); - - if (a > b) { - return false; - } else if (a < b) { - return true; - } - } - - - if (i < curList.size()) { - // 1.2.1 vs 1.2 - return false; - } else if (i < latestList.size()) { - // 1.2 vs 1.2.1 - return true; - } else { - // 1.2 vs 1.2 - return false; - } -} - -void VUpdater::parseResult(const QByteArray &p_data) -{ - m_proBar->setValue(40); - QJsonDocument jsonDoc = QJsonDocument::fromJson(p_data); - QJsonObject json = jsonDoc.object(); - - if (jsonDoc.isNull() || json.empty()) { - m_proBar->setEnabled(false); - m_proLabel->setText(tr(":( Fail to check for updates.\n" - "Please try it later.")); - - return; - } - - m_proBar->setValue(100); - - QString tag = json["tag_name"].toString(); - if (tag.startsWith('v') && tag.size() > 3) { - tag = tag.right(tag.size() - 1); - } - - QString releaseName = json["name"].toString(); - QString releaseUrl = json["html_url"].toString(); - QString body = json["body"].toString(); - - m_versionLabel->setText(tr("Current Version: v%1\nLatest Version: v%2") - .arg(g_config->c_version).arg(tag)); - if (isNewerVersion(g_config->c_version, tag)) { - m_proLabel->setText(tr("Updates Available!
" - "Please visit Github Releases to download the latest version.") - .arg(releaseUrl)); - } else { - m_proLabel->setText(tr("VNote is already the latest version.")); - } - - m_descriptionTb->setText(releaseName + "\n==========\n" + body); - m_descriptionTb->show(); - m_proBar->hide(); -} diff --git a/src/dialog/vupdater.h b/src/dialog/vupdater.h deleted file mode 100644 index d6d4a816..00000000 --- a/src/dialog/vupdater.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef VUPDATER_H -#define VUPDATER_H - -#include -#include - -class QLabel; -class QDialogButtonBox; -class QTextBrowser; -class QProgressBar; -class QShowEvent; - -class VUpdater : public QDialog -{ - Q_OBJECT -public: - VUpdater(QWidget *p_parent = 0); - -protected: - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - // Calling to Github api got responses. - void parseResult(const QByteArray &p_data); - -private: - void setupUI(); - - // Fetch the latest release info from Github. - void checkUpdates(); - - QLabel *m_versionLabel; - QTextBrowser *m_descriptionTb; - QDialogButtonBox *m_btnBox; - - // Progress label and bar. - QLabel *m_proLabel; - QProgressBar *m_proBar; -}; - -#endif // VUPDATER_H diff --git a/src/hgmarkdownhighlighter.cpp b/src/hgmarkdownhighlighter.cpp deleted file mode 100644 index 9728905e..00000000 --- a/src/hgmarkdownhighlighter.cpp +++ /dev/null @@ -1,741 +0,0 @@ -#include -#include -#include -#include -#include "hgmarkdownhighlighter.h" -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "vtextblockdata.h" - -extern VConfigManager *g_config; - -const int HGMarkdownHighlighter::initCapacity = 1024; - -void HGMarkdownHighlighter::resizeBuffer(int newCap) -{ - if (newCap == capacity) { - return; - } - if (capacity > 0) { - Q_ASSERT(content); - delete [] content; - } - capacity = newCap; - content = new char [capacity]; -} - -// Will be freeed by parent automatically -HGMarkdownHighlighter::HGMarkdownHighlighter(const QVector &styles, - const QHash &codeBlockStyles, - int waitInterval, - QTextDocument *parent) - : QSyntaxHighlighter(parent), - highlightingStyles(styles), - m_codeBlockStyles(codeBlockStyles), - m_numOfCodeBlockHighlightsToRecv(0), - parsing(0), - m_blockHLResultReady(false), - waitInterval(waitInterval), - content(NULL), - capacity(0), - result(NULL) -{ - codeBlockStartExp = QRegExp(VUtils::c_fencedCodeBlockStartRegExp); - codeBlockEndExp = QRegExp(VUtils::c_fencedCodeBlockEndRegExp); - - codeBlockFormat.setForeground(QBrush(Qt::darkYellow)); - for (int index = 0; index < styles.size(); ++index) { - const pmh_element_type &eleType = styles[index].type; - if (eleType == pmh_VERBATIM) { - codeBlockFormat = styles[index].format; - } else if (eleType == pmh_LINK) { - m_linkFormat = styles[index].format; - } else if (eleType == pmh_IMAGE) { - m_imageFormat = styles[index].format; - } - } - - m_colorColumnFormat = codeBlockFormat; - m_colorColumnFormat.setForeground(QColor(g_config->getEditorColorColumnFg())); - m_colorColumnFormat.setBackground(QColor(g_config->getEditorColorColumnBg())); - - resizeBuffer(initCapacity); - document = parent; - - timer = new QTimer(this); - timer->setSingleShot(true); - timer->setInterval(this->waitInterval); - connect(timer, &QTimer::timeout, - this, [this]() { - startParseAndHighlight(false); - }); - - static const int completeWaitTime = 500; - m_completeTimer = new QTimer(this); - m_completeTimer->setSingleShot(true); - m_completeTimer->setInterval(completeWaitTime); - connect(m_completeTimer, &QTimer::timeout, - this, &HGMarkdownHighlighter::highlightCompleted); - - connect(document, &QTextDocument::contentsChange, - this, &HGMarkdownHighlighter::handleContentChange); -} - -HGMarkdownHighlighter::~HGMarkdownHighlighter() -{ - if (result) { - pmh_free_elements(result); - result = NULL; - } - if (content) { - delete [] content; - capacity = 0; - content = NULL; - } -} - -void HGMarkdownHighlighter::updateBlockUserData(int p_blockNum, const QString &p_text) -{ - Q_UNUSED(p_text); - - VTextBlockData *blockData = dynamic_cast(currentBlockUserData()); - if (!blockData) { - blockData = new VTextBlockData(); - setCurrentBlockUserData(blockData); - } - - if (blockData->getPreviews().isEmpty()) { - m_possiblePreviewBlocks.remove(p_blockNum); - } else { - m_possiblePreviewBlocks.insert(p_blockNum); - } -} - -void HGMarkdownHighlighter::highlightBlock(const QString &text) -{ - int blockNum = currentBlock().blockNumber(); - if (m_blockHLResultReady && blockHighlights.size() > blockNum) { - const QVector &units = blockHighlights[blockNum]; - for (int i = 0; i < units.size(); ++i) { - // TODO: merge two format within the same range - const HLUnit &unit = units[i]; - setFormat(unit.start, unit.length, highlightingStyles[unit.styleIndex].format); - } - } - - // We use PEG Markdown Highlight as the main highlighter. - // We can use other highlighting methods to complement it. - - // Set current block's user data. - updateBlockUserData(blockNum, text); - - // If it is a block inside HTML comment, just skip it. - if (isBlockInsideCommentRegion(currentBlock())) { - setCurrentBlockState(HighlightBlockState::Comment); - goto exit; - } - - // PEG Markdown Highlight does not handle the ``` code block correctly. - setCurrentBlockState(HighlightBlockState::Normal); - highlightCodeBlock(text); - - // PEG Markdown Highlight does not handle links with spaces in the URL. - // Links in the URL should be encoded to %20. We just let it be here and won't - // fix this. - // highlightLinkWithSpacesInURL(text); - - // Highlight CodeBlock using VCodeBlockHighlightHelper. - if (m_codeBlockHighlights.size() > blockNum) { - const QVector &units = m_codeBlockHighlights[blockNum]; - // Manually simply merge the format of all the units within the same block. - // Using QTextCursor to get the char format after setFormat() seems - // not to work. - QVector formats; - formats.reserve(units.size()); - // formatIndex[i] is the index in @formats which is the format of the - // ith character. - QVector formatIndex(currentBlock().length(), -1); - for (int i = 0; i < units.size(); ++i) { - const HLUnitStyle &unit = units[i]; - auto it = m_codeBlockStyles.find(unit.style); - if (it != m_codeBlockStyles.end()) { - QTextCharFormat newFormat; - if (unit.start < (unsigned int)formatIndex.size() && formatIndex[unit.start] != -1) { - newFormat = formats[formatIndex[unit.start]]; - newFormat.merge(*it); - } else { - newFormat = *it; - } - setFormat(unit.start, unit.length, newFormat); - - formats.append(newFormat); - int idx = formats.size() - 1; - unsigned int endIdx = unit.length + unit.start; - for (unsigned int i = unit.start; i < endIdx && i < (unsigned int)formatIndex.size(); ++i) { - formatIndex[i] = idx; - } - } - } - } - - highlightCodeBlockColorColumn(text); - -exit: - highlightChanged(); -} - -void HGMarkdownHighlighter::initBlockHighlightFromResult(int nrBlocks) -{ - blockHighlights.resize(nrBlocks); - for (int i = 0; i < blockHighlights.size(); ++i) { - blockHighlights[i].clear(); - } - - if (!result) { - return; - } - - for (int i = 0; i < highlightingStyles.size(); i++) - { - const HighlightingStyle &style = highlightingStyles[i]; - pmh_element *elem_cursor = result[style.type]; - - // pmh_H1 to pmh_H6 is continuous. - bool isHeader = style.type >= pmh_H1 && style.type <= pmh_H6; - - while (elem_cursor != NULL) - { - // elem_cursor->pos and elem_cursor->end is the start - // and end position of the element in document. - if (elem_cursor->end <= elem_cursor->pos) { - elem_cursor = elem_cursor->next; - continue; - } - - // Check header. Skip those headers with no spaces after #s. - if (isHeader - && !isValidHeader(elem_cursor->pos, elem_cursor->end)) { - elem_cursor = elem_cursor->next; - continue; - } - - initBlockHighlihgtOne(elem_cursor->pos, elem_cursor->end, i); - elem_cursor = elem_cursor->next; - } - } -} - -void HGMarkdownHighlighter::initHtmlCommentRegionsFromResult() -{ - // From Qt5.7, the capacity is preserved. - m_commentRegions.clear(); - - if (!result) { - return; - } - - pmh_element *elem = result[pmh_COMMENT]; - while (elem != NULL) { - if (elem->end <= elem->pos) { - elem = elem->next; - continue; - } - - m_commentRegions.push_back(VElementRegion(elem->pos, elem->end)); - - elem = elem->next; - } - - qDebug() << "highlighter: parse" << m_commentRegions.size() << "HTML comment regions"; -} - -void HGMarkdownHighlighter::initImageRegionsFromResult() -{ - if (!result) { - // From Qt5.7, the capacity is preserved. - m_imageRegions.clear(); - emit imageLinksUpdated(m_imageRegions); - return; - } - - int idx = 0; - int oriSize = m_imageRegions.size(); - pmh_element *elem = result[pmh_IMAGE]; - while (elem != NULL) { - if (elem->end <= elem->pos) { - elem = elem->next; - continue; - } - - if (idx < oriSize) { - // Try to reuse the original element. - VElementRegion ® = m_imageRegions[idx]; - if ((int)elem->pos != reg.m_startPos || (int)elem->end != reg.m_endPos) { - reg.m_startPos = (int)elem->pos; - reg.m_endPos = (int)elem->end; - } - } else { - m_imageRegions.push_back(VElementRegion(elem->pos, elem->end)); - } - - ++idx; - elem = elem->next; - } - - if (idx < oriSize) { - m_imageRegions.resize(idx); - } - - qDebug() << "highlighter: parse" << m_imageRegions.size() << "image regions"; - - emit imageLinksUpdated(m_imageRegions); -} - -void HGMarkdownHighlighter::initHeaderRegionsFromResult() -{ - if (!result) { - // From Qt5.7, the capacity is preserved. - m_headerRegions.clear(); - emit headersUpdated(m_headerRegions); - return; - } - - int idx = 0; - int oriSize = m_headerRegions.size(); - pmh_element_type hx[6] = {pmh_H1, pmh_H2, pmh_H3, pmh_H4, pmh_H5, pmh_H6}; - for (int i = 0; i < 6; ++i) { - pmh_element *elem = result[hx[i]]; - while (elem != NULL) { - if (elem->end <= elem->pos - || !isValidHeader(elem->pos, elem->end)) { - elem = elem->next; - continue; - } - - if (idx < oriSize) { - // Try to reuse the original element. - VElementRegion ® = m_headerRegions[idx]; - if ((int)elem->pos != reg.m_startPos || (int)elem->end != reg.m_endPos) { - reg.m_startPos = (int)elem->pos; - reg.m_endPos = (int)elem->end; - } - } else { - m_headerRegions.push_back(VElementRegion(elem->pos, elem->end)); - } - - ++idx; - elem = elem->next; - } - } - - if (idx < oriSize) { - m_headerRegions.resize(idx); - } - - std::sort(m_headerRegions.begin(), m_headerRegions.end()); - - qDebug() << "highlighter: parse" << m_headerRegions.size() << "header regions"; - - emit headersUpdated(m_headerRegions); -} - -void HGMarkdownHighlighter::initBlockHighlihgtOne(unsigned long pos, - unsigned long end, - int styleIndex) -{ - // When the the highlight element is at the end of document, @end will equals - // to the characterCount. - unsigned int nrChar = (unsigned int)document->characterCount(); - if (end >= nrChar && nrChar > 0) { - end = nrChar - 1; - } - - int startBlockNum = document->findBlock(pos).blockNumber(); - int endBlockNum = document->findBlock(end).blockNumber(); - - for (int i = startBlockNum; i <= endBlockNum; ++i) - { - QTextBlock block = document->findBlockByNumber(i); - int blockStartPos = block.position(); - HLUnit unit; - if (i == startBlockNum) { - unit.start = pos - blockStartPos; - unit.length = (startBlockNum == endBlockNum) ? - (end - pos) : (block.length() - unit.start); - } else if (i == endBlockNum) { - unit.start = 0; - unit.length = end - blockStartPos; - } else { - unit.start = 0; - unit.length = block.length(); - } - unit.styleIndex = styleIndex; - - blockHighlights[i].append(unit); - } -} - -void HGMarkdownHighlighter::highlightCodeBlock(const QString &text) -{ - static int startLeadingSpaces = -1; - int length = 0; - int index = -1; - int preState = previousBlockState(); - int state = HighlightBlockState::Normal; - - if (preState != HighlightBlockState::CodeBlock - && preState != HighlightBlockState::CodeBlockStart) { - // Need to find a new code block start. - index = codeBlockStartExp.indexIn(text); - if (index >= 0) { - // Start a new code block. - length = text.length(); - state = HighlightBlockState::CodeBlockStart; - - // The leading spaces of code block start and end must be identical. - startLeadingSpaces = codeBlockStartExp.capturedTexts()[1].size(); - } else { - // A normal block. - startLeadingSpaces = -1; - return; - } - } else { - // Need to find a code block end. - index = codeBlockEndExp.indexIn(text); - - // The closing ``` should have the same indentation as the open ```. - if (index >= 0 - && startLeadingSpaces == codeBlockEndExp.capturedTexts()[1].size()) { - // End of code block. - length = text.length(); - state = HighlightBlockState::CodeBlockEnd; - } else { - // Within code block. - index = 0; - length = text.length(); - state = HighlightBlockState::CodeBlock; - } - } - - setCurrentBlockState(state); - setFormat(index, length, codeBlockFormat); -} - -void HGMarkdownHighlighter::highlightCodeBlockColorColumn(const QString &p_text) -{ - int cc = g_config->getColorColumn(); - if (cc <= 0 || currentBlockState() != HighlightBlockState::CodeBlock) { - return; - } - - if (p_text.size() < cc) { - return; - } - - setFormat(cc - 1, 1, m_colorColumnFormat); -} - -void HGMarkdownHighlighter::highlightLinkWithSpacesInURL(const QString &p_text) -{ - if (currentBlockState() == HighlightBlockState::CodeBlock) { - return; - } - - // TODO: should select links with spaces in URL. - QRegExp regExp("[\\!]?\\[[^\\]]*\\]\\(([^\\n\\)]+)\\)"); - int index = regExp.indexIn(p_text); - while (index >= 0) { - Q_ASSERT(regExp.captureCount() == 1); - int length = regExp.matchedLength(); - QString capturedText = regExp.capturedTexts()[1]; - if (capturedText.contains(' ')) { - if (p_text[index] == '!' && m_imageFormat.isValid()) { - setFormat(index, length, m_imageFormat); - } else if (m_linkFormat.isValid()) { - setFormat(index, length, m_linkFormat); - } - } - index = regExp.indexIn(p_text, index + length); - } -} - -void HGMarkdownHighlighter::parse(bool p_fast) -{ - if (!parsing.testAndSetRelaxed(0, 1)) { - return; - } - - if (highlightingStyles.isEmpty()) { - goto exit; - } - - { - m_blockHLResultReady = false; - - int nrBlocks = document->blockCount(); - parseInternal(); - - initBlockHighlightFromResult(nrBlocks); - - m_blockHLResultReady = true; - - if (!p_fast) { - initHtmlCommentRegionsFromResult(); - - initImageRegionsFromResult(); - - initHeaderRegionsFromResult(); - } - - if (result) { - pmh_free_elements(result); - result = NULL; - } - } - -exit: - parsing.store(0); -} - -void HGMarkdownHighlighter::parseInternal() -{ - QString text = document->toPlainText(); - QByteArray ba = text.toUtf8(); - const char *data = (const char *)ba.data(); - int len = ba.size(); - - if (result) { - pmh_free_elements(result); - result = NULL; - } - - if (len == 0) { - return; - } else if (len >= capacity) { - resizeBuffer(qMax(2 * capacity, len * 2)); - } else if (len < (capacity >> 2)) { - resizeBuffer(qMax(capacity >> 1, len * 2)); - } - - memcpy(content, data, len); - content[len] = '\0'; - - pmh_markdown_to_elements(content, pmh_EXT_NONE, &result); -} - -void HGMarkdownHighlighter::handleContentChange(int /* position */, int charsRemoved, int charsAdded) -{ - if (charsRemoved == 0 && charsAdded == 0) { - return; - } - - timer->stop(); - timer->start(); -} - -void HGMarkdownHighlighter::startParseAndHighlight(bool p_fast) -{ - qDebug() << "HGMarkdownHighlighter start a new parse (fast" << p_fast << ")"; - parse(p_fast); - - if (p_fast) { - rehighlight(); - } else { - if (!updateCodeBlocks()) { - rehighlight(); - } - - highlightChanged(); - } -} - -void HGMarkdownHighlighter::updateHighlight() -{ - timer->stop(); - startParseAndHighlight(false); -} - -void HGMarkdownHighlighter::updateHighlightFast() -{ - timer->stop(); - startParseAndHighlight(true); -} - -bool HGMarkdownHighlighter::updateCodeBlocks() -{ - if (!g_config->getEnableCodeBlockHighlight()) { - m_codeBlockHighlights.clear(); - return false; - } - - m_codeBlockHighlights.resize(document->blockCount()); - for (int i = 0; i < m_codeBlockHighlights.size(); ++i) { - m_codeBlockHighlights[i].clear(); - } - - QVector codeBlocks; - - VCodeBlock item; - bool inBlock = false; - int startLeadingSpaces = -1; - - // Only handle complete codeblocks. - QTextBlock block = document->firstBlock(); - while (block.isValid()) { - QString text = block.text(); - if (inBlock) { - item.m_text = item.m_text + "\n" + text; - int idx = codeBlockEndExp.indexIn(text); - if (idx >= 0 && codeBlockEndExp.capturedTexts()[1].size() == startLeadingSpaces) { - // End block. - inBlock = false; - item.m_endBlock = block.blockNumber(); - - // See if it is a code block inside HTML comment. - if (!isBlockInsideCommentRegion(block)) { - qDebug() << "add one code block in lang" << item.m_lang; - codeBlocks.append(item); - } - } - } else { - int idx = codeBlockStartExp.indexIn(text); - if (idx >= 0) { - // Start block. - inBlock = true; - item.m_startBlock = block.blockNumber(); - item.m_startPos = block.position(); - item.m_text = text; - if (codeBlockStartExp.captureCount() == 2) { - item.m_lang = codeBlockStartExp.capturedTexts()[2]; - } - - startLeadingSpaces = codeBlockStartExp.capturedTexts()[1].size(); - } - } - - block = block.next(); - } - - m_numOfCodeBlockHighlightsToRecv = codeBlocks.size(); - if (m_numOfCodeBlockHighlightsToRecv > 0) { - emit codeBlocksUpdated(codeBlocks); - return true; - } else { - return false; - } -} - -static bool HLUnitStyleComp(const HLUnitStyle &a, const HLUnitStyle &b) -{ - if (a.start < b.start) { - return true; - } else if (a.start == b.start) { - return a.length > b.length; - } else { - return false; - } -} - -void HGMarkdownHighlighter::setCodeBlockHighlights(const QVector &p_units) -{ - if (p_units.isEmpty()) { - goto exit; - } - - { - QVector> highlights(m_codeBlockHighlights.size()); - - for (auto const &unit : p_units) { - int pos = unit.m_position; - int end = unit.m_position + unit.m_length; - int startBlockNum = document->findBlock(pos).blockNumber(); - int endBlockNum = document->findBlock(end).blockNumber(); - - // Text has been changed. Abandon the obsolete parsed result. - if (startBlockNum == -1 || endBlockNum >= highlights.size()) { - goto exit; - } - - for (int i = startBlockNum; i <= endBlockNum; ++i) - { - QTextBlock block = document->findBlockByNumber(i); - int blockStartPos = block.position(); - HLUnitStyle hl; - hl.style = unit.m_style; - if (i == startBlockNum) { - hl.start = pos - blockStartPos; - hl.length = (startBlockNum == endBlockNum) ? - (end - pos) : (block.length() - hl.start); - } else if (i == endBlockNum) { - hl.start = 0; - hl.length = end - blockStartPos; - } else { - hl.start = 0; - hl.length = block.length(); - } - - highlights[i].append(hl); - } - } - - // Need to highlight in order. - for (int i = 0; i < highlights.size(); ++i) { - QVector &units = highlights[i]; - if (!units.isEmpty()) { - std::sort(units.begin(), units.end(), HLUnitStyleComp); - m_codeBlockHighlights[i].append(units); - } - } - } - -exit: - --m_numOfCodeBlockHighlightsToRecv; - if (m_numOfCodeBlockHighlightsToRecv <= 0) { - rehighlight(); - } -} - -bool HGMarkdownHighlighter::isBlockInsideCommentRegion(const QTextBlock &p_block) const -{ - if (!p_block.isValid()) { - return false; - } - - int start = p_block.position(); - int end = start + p_block.length(); - - for (auto const & reg : m_commentRegions) { - if (reg.contains(start) && reg.contains(end)) { - return true; - } - } - - return false; -} - -void HGMarkdownHighlighter::highlightChanged() -{ - m_completeTimer->stop(); - m_completeTimer->start(); -} - -bool HGMarkdownHighlighter::isValidHeader(unsigned long p_pos, unsigned long p_end) -{ - // There must exist spaces after #s. - // No more than 6 #s. - int nrNumberSign = 0; - for (unsigned long i = p_pos; i < p_end; ++i) { - QChar ch = document->characterAt(i); - if (ch.isSpace()) { - return true; - } else if (ch == QChar('#')) { - if (++nrNumberSign > 6) { - return false; - } - } else { - return false; - } - } - - return false; -} diff --git a/src/hgmarkdownhighlighter.h b/src/hgmarkdownhighlighter.h deleted file mode 100644 index 8738b986..00000000 --- a/src/hgmarkdownhighlighter.h +++ /dev/null @@ -1,276 +0,0 @@ -#ifndef HGMARKDOWNHIGHLIGHTER_H -#define HGMARKDOWNHIGHLIGHTER_H - -#include -#include -#include -#include -#include -#include - -extern "C" { -#include -} - -QT_BEGIN_NAMESPACE -class QTextDocument; -QT_END_NAMESPACE - -struct HighlightingStyle -{ - pmh_element_type type; - QTextCharFormat format; -}; - -// One continuous region for a certain markdown highlight style -// within a QTextBlock. -// Pay attention to the change of HighlightingStyles[] -struct HLUnit -{ - // Highlight offset @start and @length with style HighlightingStyles[styleIndex] - // within a QTextBlock - unsigned long start; - unsigned long length; - unsigned int styleIndex; -}; - -struct HLUnitStyle -{ - unsigned long start; - unsigned long length; - QString style; -}; - -// Fenced code block only. -struct VCodeBlock -{ - int m_startPos; - int m_startBlock; - int m_endBlock; - QString m_lang; - - QString m_text; -}; - -// Highlight unit with global position and string style name. -struct HLUnitPos -{ - HLUnitPos() : m_position(-1), m_length(-1) - { - } - - HLUnitPos(int p_position, int p_length, const QString &p_style) - : m_position(p_position), m_length(p_length), m_style(p_style) - { - } - - int m_position; - int m_length; - QString m_style; -}; - -// Denote the region of a certain Markdown element. -struct VElementRegion -{ - VElementRegion() : m_startPos(0), m_endPos(0) {} - - VElementRegion(int p_start, int p_end) : m_startPos(p_start), m_endPos(p_end) {} - - // The start position of the region in document. - int m_startPos; - - // The end position of the region in document. - int m_endPos; - - // Whether this region contains @p_pos. - bool contains(int p_pos) const - { - return m_startPos <= p_pos && m_endPos >= p_pos; - } - - bool operator==(const VElementRegion &p_other) const - { - return (m_startPos == p_other.m_startPos - && m_endPos == p_other.m_endPos); - } - - bool operator<(const VElementRegion &p_other) const - { - if (m_startPos < p_other.m_startPos) { - return true; - } else if (m_startPos == p_other.m_startPos) { - return m_endPos <= p_other.m_endPos; - } else { - return false; - } - } -}; - -class HGMarkdownHighlighter : public QSyntaxHighlighter -{ - Q_OBJECT - -public: - HGMarkdownHighlighter(const QVector &styles, - const QHash &codeBlockStyles, - int waitInterval, - QTextDocument *parent = 0); - ~HGMarkdownHighlighter(); - - // Request to update highlihgt (re-parse and re-highlight) - void setCodeBlockHighlights(const QVector &p_units); - - const QMap &getPotentialPreviewBlocks() const; - - const QVector &getHeaderRegions() const; - - const QSet &getPossiblePreviewBlocks() const; - - void clearPossiblePreviewBlocks(const QVector &p_blocksToClear); - - // Parse and only update the highlight results for rehighlight(). - void updateHighlightFast(); - -signals: - void highlightCompleted(); - - // QVector is implicitly shared. - void codeBlocksUpdated(const QVector &p_codeBlocks); - - // Emitted when image regions have been fetched from a new parsing result. - void imageLinksUpdated(const QVector &p_imageRegions); - - // Emitted when header regions have been fetched from a new parsing result. - void headersUpdated(const QVector &p_headerRegions); - -protected: - void highlightBlock(const QString &text) Q_DECL_OVERRIDE; - -public slots: - // Parse and rehighlight immediately. - void updateHighlight(); - -private slots: - void handleContentChange(int position, int charsRemoved, int charsAdded); - - // @p_fast: if true, just parse and update styles. - void startParseAndHighlight(bool p_fast = false); - -private: - QRegExp codeBlockStartExp; - QRegExp codeBlockEndExp; - QTextCharFormat codeBlockFormat; - QTextCharFormat m_linkFormat; - QTextCharFormat m_imageFormat; - QTextCharFormat m_colorColumnFormat; - - QTextDocument *document; - QVector highlightingStyles; - QHash m_codeBlockStyles; - QVector > blockHighlights; - - // Use another member to store the codeblocks highlights, because the highlight - // sequence is blockHighlights, regular-expression-based highlihgts, and then - // codeBlockHighlights. - // Support fenced code block only. - QVector > m_codeBlockHighlights; - - int m_numOfCodeBlockHighlightsToRecv; - - // All HTML comment regions. - QVector m_commentRegions; - - // All image link regions. - QVector m_imageRegions; - - // All header regions. - // May contains illegal elements. - // Sorted by start position. - QVector m_headerRegions; - - // Timer to signal highlightCompleted(). - QTimer *m_completeTimer; - - QAtomicInt parsing; - - // Whether highlight results for blocks are ready. - bool m_blockHLResultReady; - - QTimer *timer; - int waitInterval; - - // Block number of those blocks which possible contains previewed image. - QSet m_possiblePreviewBlocks; - - char *content; - int capacity; - pmh_element **result; - - static const int initCapacity; - - void resizeBuffer(int newCap); - void highlightCodeBlock(const QString &text); - - // Highlight links using regular expression. - // PEG Markdown Highlight treat URLs with spaces illegal. This function is - // intended to complement this. - void highlightLinkWithSpacesInURL(const QString &p_text); - - void parse(bool p_fast = false); - - void parseInternal(); - - // Init highlight elements for all the blocks from parse results. - void initBlockHighlightFromResult(int nrBlocks); - - // Init highlight elements for blocks from one parse result. - void initBlockHighlihgtOne(unsigned long pos, - unsigned long end, - int styleIndex); - - // Return true if there are fenced code blocks and it will call rehighlight() later. - // Return false if there is none. - bool updateCodeBlocks(); - - // Fetch all the HTML comment regions from parsing result. - void initHtmlCommentRegionsFromResult(); - - // Fetch all the image link regions from parsing result. - void initImageRegionsFromResult(); - - // Fetch all the header regions from parsing result. - void initHeaderRegionsFromResult(); - - // Whether @p_block is totally inside a HTML comment. - bool isBlockInsideCommentRegion(const QTextBlock &p_block) const; - - // Highlights have been changed. Try to signal highlightCompleted(). - void highlightChanged(); - - // Set the user data of currentBlock(). - void updateBlockUserData(int p_blockNum, const QString &p_text); - - // Highlight color column in code block. - void highlightCodeBlockColorColumn(const QString &p_text); - - // Check if [p_pos, p_end) is a valid header. - bool isValidHeader(unsigned long p_pos, unsigned long p_end); -}; - -inline const QVector &HGMarkdownHighlighter::getHeaderRegions() const -{ - return m_headerRegions; -} - -inline const QSet &HGMarkdownHighlighter::getPossiblePreviewBlocks() const -{ - return m_possiblePreviewBlocks; -} - -inline void HGMarkdownHighlighter::clearPossiblePreviewBlocks(const QVector &p_blocksToClear) -{ - for (auto i : p_blocksToClear) { - m_possiblePreviewBlocks.remove(i); - } -} -#endif diff --git a/src/lineeditdelegate.cpp b/src/lineeditdelegate.cpp deleted file mode 100644 index d424d255..00000000 --- a/src/lineeditdelegate.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "lineeditdelegate.h" - -#include - - -LineEditDelegate::LineEditDelegate(QObject *p_parent) - : QStyledItemDelegate(p_parent) -{ -} - -QWidget *LineEditDelegate::createEditor(QWidget *p_parent, - const QStyleOptionViewItem &p_option, - const QModelIndex &p_index) const -{ - Q_UNUSED(p_option); - Q_UNUSED(p_index); - - QLineEdit *edit = new QLineEdit(p_parent); - return edit; -} - -void LineEditDelegate::setEditorData(QWidget *p_editor, const QModelIndex &p_index) const -{ - QString text = p_index.model()->data(p_index, Qt::EditRole).toString(); - - QLineEdit *edit = static_cast(p_editor); - edit->setText(text); -} - -void LineEditDelegate::setModelData(QWidget *p_editor, - QAbstractItemModel *p_model, - const QModelIndex &p_index) const -{ - QLineEdit *edit = static_cast(p_editor); - - p_model->setData(p_index, edit->text(), Qt::EditRole); -} - -void LineEditDelegate::updateEditorGeometry(QWidget *p_editor, - const QStyleOptionViewItem &p_option, - const QModelIndex &p_index) const -{ - Q_UNUSED(p_index); - p_editor->setGeometry(p_option.rect); -} diff --git a/src/lineeditdelegate.h b/src/lineeditdelegate.h deleted file mode 100644 index 018a6821..00000000 --- a/src/lineeditdelegate.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef LINEEDITDELEGATE_H -#define LINEEDITDELEGATE_H - -#include - - -class LineEditDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - LineEditDelegate(QObject *p_parent = nullptr); - - QWidget *createEditor(QWidget *p_parent, - const QStyleOptionViewItem &p_option, - const QModelIndex &p_index) const Q_DECL_OVERRIDE; - - void setEditorData(QWidget *p_editor, const QModelIndex &p_index) const Q_DECL_OVERRIDE; - - void setModelData(QWidget *p_editor, - QAbstractItemModel *p_model, - const QModelIndex &p_index) const Q_DECL_OVERRIDE; - - void updateEditorGeometry(QWidget *p_editor, - const QStyleOptionViewItem &p_option, - const QModelIndex &p_index) const Q_DECL_OVERRIDE; -}; - -#endif // LINEEDITDELEGATE_H diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index 51e453e5..00000000 --- a/src/main.cpp +++ /dev/null @@ -1,188 +0,0 @@ -#include "vmainwindow.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "utils/vutils.h" -#include "vsingleinstanceguard.h" -#include "vconfigmanager.h" -#include "vpalette.h" - -VConfigManager *g_config; - -VPalette *g_palette; - -#if defined(QT_NO_DEBUG) -// 5MB log size. -#define MAX_LOG_SIZE 5 * 1024 * 1024 - -QFile g_logFile; - -static void initLogFile(const QString &p_file) -{ - g_logFile.setFileName(p_file); - if (g_logFile.size() >= MAX_LOG_SIZE) { - g_logFile.open(QIODevice::WriteOnly | QIODevice::Text); - } else { - g_logFile.open(QIODevice::Append | QIODevice::Text); - } -} -#endif - -void VLogger(QtMsgType type, const QMessageLogContext &context, const QString &msg) -{ - QByteArray localMsg = msg.toUtf8(); - QString header; - - switch (type) { - case QtDebugMsg: - header = "Debug:"; - break; - - case QtInfoMsg: - header = "Info:"; - break; - - case QtWarningMsg: - header = "Warning:"; - break; - - case QtCriticalMsg: - header = "Critical:"; - break; - - case QtFatalMsg: - header = "Fatal:"; - } - -#if defined(QT_NO_DEBUG) - Q_UNUSED(context); - - QTextStream stream(&g_logFile); - - stream << header << localMsg << "\n"; - - if (type == QtFatalMsg) { - g_logFile.close(); - abort(); - } - -#else - std::string fileStr = QFileInfo(context.file).fileName().toStdString(); - const char *file = fileStr.c_str(); - - switch (type) { - case QtDebugMsg: - fprintf(stderr, "%s(%s:%u) %s\n", - header.toStdString().c_str(), file, context.line, localMsg.constData()); - break; - case QtInfoMsg: - fprintf(stderr, "%s(%s:%u) %s\n", - header.toStdString().c_str(), file, context.line, localMsg.constData()); - break; - case QtWarningMsg: - fprintf(stderr, "%s(%s:%u) %s\n", - header.toStdString().c_str(), file, context.line, localMsg.constData()); - break; - case QtCriticalMsg: - fprintf(stderr, "%s(%s:%u) %s\n", - header.toStdString().c_str(), file, context.line, localMsg.constData()); - break; - case QtFatalMsg: - fprintf(stderr, "%s(%s:%u) %s\n", - header.toStdString().c_str(), file, context.line, localMsg.constData()); - abort(); - } - - fflush(stderr); -#endif -} - -int main(int argc, char *argv[]) -{ - VSingleInstanceGuard guard; - bool canRun = guard.tryRun(); - - QTextCodec *codec = QTextCodec::codecForName("UTF8"); - if (codec) { - QTextCodec::setCodecForLocale(codec); - } - - QApplication app(argc, argv); - - // The file path passed via command line arguments. - QStringList filePaths = VUtils::filterFilePathsToOpen(app.arguments().mid(1)); - - if (!canRun) { - // Ask another instance to open files passed in. - if (!filePaths.isEmpty()) { - guard.openExternalFiles(filePaths); - } else { - guard.showInstance(); - } - - return 0; - } - - VConfigManager vconfig; - vconfig.initialize(); - g_config = &vconfig; - -#if defined(QT_NO_DEBUG) - initLogFile(vconfig.getLogFilePath()); -#endif - - qInstallMessageHandler(VLogger); - - QString locale = VUtils::getLocale(); - // Set default locale. - if (locale == "zh_CN") { - QLocale::setDefault(QLocale(QLocale::Chinese, QLocale::China)); - } - - qDebug() << "command line arguments" << app.arguments(); - qDebug() << "files to open from arguments" << filePaths; - - // Check the openSSL. - qDebug() << "openSSL" << QSslSocket::sslLibraryBuildVersionString() - << QSslSocket::sslLibraryVersionNumber(); - - // load translation for Qt - QTranslator qtTranslator; - if (!qtTranslator.load("qt_" + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { - qtTranslator.load("qt_" + locale, "translations"); - } - - app.installTranslator(&qtTranslator); - - // load translation for vnote - QTranslator translator; - if (translator.load("vnote_" + locale, ":/translations")) { - app.installTranslator(&translator); - } - - VPalette palette(g_config->getThemeFile()); - g_palette = &palette; - - VMainWindow w(&guard); - QString style = palette.fetchQtStyleSheet(); - if (!style.isEmpty()) { - app.setStyleSheet(style); - } - - w.show(); - - w.openStartupPages(); - - w.openFiles(filePaths); - - w.promptNewNotebookIfEmpty(); - - return app.exec(); -} diff --git a/src/resources/docs/markdown_guide_en.md b/src/resources/docs/markdown_guide_en.md deleted file mode 100644 index 536852f7..00000000 --- a/src/resources/docs/markdown_guide_en.md +++ /dev/null @@ -1,143 +0,0 @@ -# Markdown Guide -This is a quick guide [^1] for Markdown, a lightweight and easy-to-use syntax for writing. - -## What is Markdown? -Markdown is a way to style text via a few simple marker characters. You could write the document in plain text and then read it with a beautiful typesetting. - -There is no a standard Markdown syntax and many editor will add its own additional syntax. VNote supports only the widely-used basic syntax. - -## How to Use Markdown? -If you are new to Markdown, it is better to learn the syntax elements step by step. Knowing headers and emphasis is enough to make you survive. You could learn another new syntax and practise it every one or two days. - -## Syntax Guide -Here is an overview of Markdown syntax supported by VNote. - -### Headers -```md -# This is an

tag -## This is an

tag -###### This is an

tag -``` - -**Notes**: - -- At least one space is needed after the `#`; -- A header should occupy one entire line; - -### Emphasis -```md -*This text will be italic* -_This text will be italic_ - -**This text will be bold** -__This text will be bold__ -``` - -**Notes**: - -- `*` is recommended in VNote; -- If the render failed, try to add an additional space before the first `*` and after the last `*`. The space is necessary if the surrounded text begins or ends with full width punctuation; -- VNote provides shortcuts `Ctrl+I` and `Ctrl+B` to insert italic and bold text; - -### Lists -#### Unordered -```md -* Item 1 -This is a text under Item 1. Notice that there are two spaces at the end above. -* Item 2 - * Item 2a - * Item 2b -* Item 3 - -To end a list, there should be one empty line above. -``` - -#### Ordered -```md -1. Item 1 -1. Item 2 -Notice that the sequence number is irrelevant. Markdown will change the sequence automatically when renderring. -3. Item 3 - 1. Item 3a - 2. Item 3b -4. Item 4 -``` - -### Images and Links -```md -![Image Alt Text](/url/to/images.png) - -[Link Text](/url/of/the/link) -``` - -**Notes**: - -- It is not recommended to use image links in reference format. VNote will not preview those images. - -### Blockquotes -```md -As VNote suggests: - -> VNote is the best Markdown note-taking application -> ever. -> -> THere is two spaces after `ever.` above to insert a -> new line. -``` - -**Notes**: - -- Space is needed after the marker `>`; -- You could just add only one `>` at the first line; - -### Fenced Code Block - ```lang - This is a fenced code block. - ``` - -**Notes**: - -- `lang` is optional to specify the language of the code; - -### Inline Code -```md -Here is a `inline code`. -``` - -### Strikethrough -```md -Here is a ~~text~~ with strikethrough. -``` - -**Notes**: - -- VNote provides shortcuts `Ctrl+D` to insert text with strikethrough; - -### Task Lists -```md -- [x] this is a complete item. -- [ ] this is an incomplete item. -``` - -### Subscript and Superscript -```md -This is a text with subscript H~2~o. - -This is a text with superscript 29^th^. -``` - -### Footnote -```md -This is a footnote [^1]. - -[^1]: Here is the detail of the footnote. -``` - -### New Line and Paragraph -If you want to enter a new line, you should add two spaces after current line and then continue your input. VNote provides `Shift+Enter` to help. - -If you want to enter a new paragraph, you should add an empty line and then continue entering the new paragraph. - -Generally, you need to add an empty line after a block element (such as code block, lists, blockquote) to explicitly end it. - -[^1]: This guide references [Mastering Markdown](https://guides.github.com/features/mastering-markdown/). diff --git a/src/resources/docs/markdown_guide_zh.md b/src/resources/docs/markdown_guide_zh.md deleted file mode 100644 index ac815020..00000000 --- a/src/resources/docs/markdown_guide_zh.md +++ /dev/null @@ -1,144 +0,0 @@ -# Markdown指南 -Markdown是一种轻量级的易用的书写语法。本文是Markdown的一个快速指南[^1]。 - -## 什么是Markdown? -Markdown是一种通过少量简单的标记字符来格式化文本的方法。您可以用纯文本来书写文档,然后在阅读时呈现一个美观的排版。 - -其实并没有一个标准的Markdown语法,很多编辑器都会添加自己的扩展语法。不同于此,为了兼容性,VNote仅仅支持那些被广泛使用的基本语法。 - -## 如何上手Markdown? -如果您是刚接触Markdown,那么比较好的一个方法是逐个学习Markdown语法。刚开始,懂得标题和强调语法就能够写出基本的文档;然后,每天可以学习一个新的语法并不断练习。 - - -## 语法指南 -下面是VNote支持的Markdown语法的一个概览。 - -### 标题 -```md -# This is an

tag -## This is an

tag -###### This is an

tag -``` - -**注意**: - -- `#`之后需要至少一个空格; -- 一个标题应该占一整行; - -### 强调 -```md -*This text will be italic* -_This text will be italic_ - -**This text will be bold** -__This text will be bold__ -``` - -**注意**: - -- VNote推荐使用`*`; -- 如果渲染错误,请尝试在第一个`*`之前以及最后一个`*`之后添加一个空格。如果被标记的文本是以全角符号开始或结尾,一般都需要前后添加一个空格; -- VNote提供快捷键`Ctrl+I`和`Ctrl+B`来插入斜体和粗体; - -### 列表 -#### 无序列表 -```md -* Item 1 -只是一段在Item 1下面的文字。需要注意上面一行结尾有两个空格。 -* Item 2 - * Item 2a - * Item 2b -* Item 3 - -使用一个空行来来结束一个列表。 -``` - -#### 有序列表 -```md -1. Item 1 -1. Item 2 -注意,列表前面的序号其实是无关紧要的,渲染时Markdown会自动修改该序号。 -3. Item 3 - 1. Item 3a - 2. Item 3b -4. Item 4 -``` - -### 图片和链接 -```md -![Image Alt Text](/url/to/images.png) - -[Link Text](/url/of/the/link) -``` - -**注意**: - -- VNote不推荐使用参考式的图片链接。VNote不会预览这些图片。 - -### 块引用 -```md -As VNote suggests: - -> VNote is the best Markdown note-taking application -> ever. -> -> THere is two spaces after `ever.` above to insert a -> new line. -``` - -**注意**: - -- `>`标记后面需要至少一个空格; -- 多行连续的引用可以只在第一行添加标记; - -### 代码块 - ```lang - This is a fenced code block. - ``` - -**注意**: - -- `lang`用于指定代码块的代码语言,可选; - -### 行内代码 -```md -Here is a `inline code`. -``` - -### 删除线 -```md -Here is a ~~text~~ with strikethrough. -``` - -**注意**: - -- VNote提供快捷键`Ctrl+D`来插入带有删除线的文本; - -### 任务列表 -```md -- [x] this is a complete item. -- [ ] this is an incomplete item. -``` - -### 上标和下标 -```md -This is a text with subscript H~2~o. - -This is a text with superscript 29^th^. -``` - -### 脚注 -```md -This is a footnote [^1]. - -[^1]: Here is the detail of the footnote. -``` - -### 换行和段落 -如果需要换行,您应该在当前行末尾添加两个空格,然后换行。VNote提供快捷键`Shift+Enter`来辅助用户输入两个空格并换行。 - -如果需要一个新的段落,您应该先插入一个空行然后才输入新的段落的文本。 - -一般来说,您应该在一个块元素(例如代码块、列表和块引用)后面插入一个空行来显式结束该元素。 - -[^1]: 该指南参考了 [Mastering Markdown](https://guides.github.com/features/mastering-markdown/). diff --git a/src/resources/docs/shortcuts_en.md b/src/resources/docs/shortcuts_en.md deleted file mode 100644 index b7dc153f..00000000 --- a/src/resources/docs/shortcuts_en.md +++ /dev/null @@ -1,271 +0,0 @@ -# VNote Shortcuts -1. All the keys without special notice are **case insensitive**; -2. On macOS, `Ctrl` corresponds to `Command` except in Vim mode. - -## Normal Shortcuts -- `Ctrl+E E` -Toggle expanding the edit area. -- `Ctrl+Alt+N` -Create a note in current folder. -- `Ctrl+F` -Find/Replace in current note. -- `Ctrl+Q` -Quit VNote. -- `Ctrl+J`/`Ctrl+K` -VNote supports `Ctrl+J` and `Ctrl+K` for navigation in the notebooks list, directories list, notes list, opened notes list, and outline list. -- `Ctrl+Left Mouse` -Scroll in all directions. -- `Ctrl+Shift+T` -Recover last closed file. -- `Ctrl+Alt+L` -Open Flash Page. - -### Read Mode -- `Ctrl+W` -Edit current note. -- `H`/`J`/`K`/`L` -Navigation, corresponding to Left/Down/Up/Right arrow keys. -- `Ctrl+U` -Scroll up half screen. -- `Ctrl+D` -Scroll down half screen. -- `gg`/`G` -Jump to the beginning or end of the note. (Case Sensitive). -- `Ctrl + +/-` -Zoom in/out the page. -- `Ctrl+Wheel` -Zoom in/out the page through the mouse scroll. -- `Ctrl+0` -Recover the page zoom factor to 100%. -- Jump between titles - - `[[`: jump to previous title; - - `]]`: jump to next title; - - `[]`: jump to previous title at the same level; - - `][`: jump to next title at the same level; - - `[{`: jump to previous title at a higher level; - - `]}`: jump to next title at a higher level; - -### Edit Mode -- `Ctrl+S` -Save current changes. -- `Ctrl+T` -Save current changes and exit edit mode. - -#### Text Editing -- `Ctrl+B` -Insert bold. Press `Ctrl+B` again to exit. Current selected text will be changed to bold if exists. -- `Ctrl+I` -Insert italic. Press `Ctrl+I` again to exit. Current selected text will be changed to italic if exists. -- `Ctrl+D` -Insert strikethrought. Press `Ctrl+D` again to exit. Current selected text will be changed to strikethrough if exists. -- `Ctrl+K` -Insert inline code. Press `Ctrl+K` again to exit. Current selected text will be changed to inline code if exists. -- `Ctrl+M` -Insert fenced code block. Press `Ctrl+M` again to exit. Current selected text will be wrapped into a code block if exists. -- `Ctrl+L` -Insert link. -- `Ctrl+'` -Insert image. -- `Ctrl+H` -Backspace. Delete a character backward. -- `Ctrl+W` -Delete all the characters from current cursor to the first space backward. -- `Ctrl+U` -Delete all the characters from current cursor to the beginning of current line. -- `Ctrl+` -Insert title at level ``. `` should be 1 to 6. Current selected text will be changed to title if exists. -- `Ctrl+7` -Delete the title mark of current line or selected text. -- `Tab`/`Shift+Tab` -Increase or decrease the indentation. If any text is selected, the indentation will operate on all these selected lines. -- `Shift+Enter` -Insert two spaces followed by a new line, namely a soft linebreak in Markdown. -- `Shift+Left`, `Shift+Right`, `Shift+Up`, `Shift+Down` -Expand the selection one character left or right, or one line up or down. -- `Ctrl+Shift+Left`, `Ctrl+Shift+Right` -Expand the selection to the beginning or end of current word. -- `Ctrl+Shift+Up`, `Ctrl+Sfhit+Down` -Expand the selection to the beginning or end of current paragraph. -- `Shift+Home`, `Shift+End` -Expand the selection to the beginning or end of current line. -- `Ctrl+Shift+Home`, `Ctrl+Shift+End` -Expand the selection to the beginning or end of current note. - -## Custom Shortcuts -VNote supports customing some standard shortcuts, though it is not recommended. VNote stores shortcuts' configuration information in the `[shortcuts]` and `[captain_mode_shortcuts]` sections of user configuration file `vnote.ini`. - -For example, the default configruation may look like this: - -```ini -[shortcuts] -; Define shortcuts here, with each item in the form "operation=keysequence". -; Leave keysequence empty to disable the shortcut of an operation. -; Custom shortcuts may conflict with some key bindings in edit mode or Vim mode. -; Ctrl+Q is reserved for quitting VNote. - -; Leader key of Captain mode -CaptainMode=Ctrl+E -; Create a note in current folder -NewNote=Ctrl+Alt+N -; Save current note -SaveNote=Ctrl+S -; Save changes and enter read mode -SaveAndRead=Ctrl+T -; Edit current note -EditNote=Ctrl+W -; Close current note -CloseNote= -; Open file/replace dialog -Find=Ctrl+F -; Find next occurence -FindNext=F3 -; Find previous occurence -FindPrevious=Shift+F3 - -[captain_mode_shortcuts] -; Define shortcuts in Captain mode here. -; There shortcuts are the sub-sequence after the CaptainMode key sequence -; in [shortcuts]. - -; Enter Navigation mode -NavigationMode=W -; Show attachment list of current note -AttachmentList=A -; Locate to the folder of current note -LocateCurrentFile=D -; Toggle Expand mode -ExpandMode=E -; Alternate one/two panels view -OnePanelView=P -; Discard changes and enter read mode -DiscardAndRead=Q -; Toggle Tools dock widget -ToolsDock=T -; Close current note -CloseNote=X -; Show shortcuts help document -ShortcutsHelp=? -; Flush the log file -FlushLogFile=";" -; Show opened files list -OpenedFileList=F -; Activate the ith tab -ActivateTab1=1 -ActivateTab2=2 -ActivateTab3=3 -ActivateTab4=4 -ActivateTab5=5 -ActivateTab6=6 -ActivateTab7=7 -ActivateTab8=8 -ActivateTab9=9 -; Alternate between current and last tab -AlternateTab=0 -; Activate next tab -ActivateNextTab=J -; Activate previous tab -ActivatePreviousTab=K -; Activate the window split on the left -ActivateSplitLeft=H -; Activate the window split on the right -ActivateSplitRight=L -; Move current tab one split left -MoveTabSplitLeft=Shift+H -; Move current tab one split right -MoveTabSplitRight=Shift+L -; Create a vertical split -VerticalSplit=V -; Remove current split -RemoveSplit=R -``` - -Each item is in the form `operation=keysequence`, with `keysequence` empty to disable shortcuts for that operation. - -Pay attention that `Ctrl+Q` is reserved for quitting VNote. - -# Captain Mode -To efficiently utilize the shortcuts, VNote supports the **Captain Mode**. - -Press the leader key `Ctrl+E`, then VNote will enter the Captain Mode, within which VNote supports more efficient shortcuts. - -- `E` -Toggle expanding the edit area. -- `P` -Toggle single panel or two panels mode. -- `T` -Toggle the Tools panel. -- `F` -Popup the opened notes list of current split window. Within this list, pressing the sequence number in front of each note could jump to that note. -- `A` -Popup the attachments list of current note. -- `X` -Close current tab. -- `J` -Jump to next tab. -- `K` -Jump to last tab. -- `1` - `9` -Number key 1 to 9 will jump to the tabs with corresponding sequence number. -- `0` -Jump to previous tab. Alternate between current and previous tab. -- `D` -Locate to the folder of current note. -- `Q` -Discard current changes and exit edit mode. -- `V` -Vertically split current window. -- `R` -Remove current split window. -- `H` -Jump to the first split window on the left. -- `L` -Jump to the first split window on the right. -- `Shift+H` -Move current tab one split window left. -- `Shift+L` -Move current tab one split window right. -- `M` -Evaluate current cursor word or selected text as magic words. -- `S` -Apply a snippet in edit mode. -- `?` -Display shortcuts documentation. - -## Navigation Mode -Within the Captain Mode, `W` will turn VNote into **Navigation Mode**. In this mode, VNote will display at most two characters on some major widgets, and then pressing corresponding characters will jump to that widget. - -# Vim Mode -VNote supports a simple but useful Vim mode, including **Normal**, **Insert**, **Visual**, and **VisualLine** modes. - -VNote supports following features of Vim: - -- `r`, `s`, `S`, `i`, `I`, `a`, `A`, `c`, `C`, `o`, and `O`; -- Actions `d`, `c`, `y`, `p`, `<`, `>`, `gu`, `gU`, `J`, `gJ`, and `~`; -- Movements `h/j/k/l`, `gj/gk/g0`, `Ctrl+U`, `Ctrl+D`, `gg`, `G`, `0`, `^`, `{`, `}`, and `$`; -- Marks `a-z`; -- Registers `"`, `_`, `+`, `a-z`(`A-Z`); -- Jump locations list (`Ctrl+O` and `Ctrl+I`); -- Leader key (`Space`) - - Currently `y/d/p` equals to `"+y/d/p`, which will access the system's clipboard; - - `` to clear search highlight; - - `w` to save note; -- `zz`, `zb`, `zt`; -- `u` and `Ctrl+R` for undo and redo; -- Text objects `i/a`: word, WORD, `''`, `""`, `` ` ` ``, `()`, `[]`, `<>`, and `{}`; -- Command line `:w`, `:wq`, `:x`, `:q`, `:q!`, and `:nohlsearch`; -- Jump between titles - - `[[`: jump to previous title; - - `]]`: jump to next title; - - `[]`: jump to previous title at the same level; - - `][`: jump to next title at the same level; - - `[{`: jump to previous title at a higher level; - - `]}`: jump to next title at a higher level; -- `/` and `?` to search - - `n` and `N` to find next or previous occurence; - - `Ctrl+N` and `Ctrl+P` to navigate through the search history; -- `Ctrl+R` to read the content of a register; -- `Ctrl+O` in Insert mode to enter Normal mode temporarily; - -For now, VNote does **NOT** support the macro and repeat(`.`) features of Vim. - -Enjoy Vim in VNote! diff --git a/src/resources/docs/shortcuts_zh.md b/src/resources/docs/shortcuts_zh.md deleted file mode 100644 index a8b345a6..00000000 --- a/src/resources/docs/shortcuts_zh.md +++ /dev/null @@ -1,272 +0,0 @@ -# VNote快捷键说明 -1. 以下按键除特别说明外,都不区分大小写; -2. 在macOS下,`Ctrl`对应于`Command`,在Vim模式下除外。 - -## 常规快捷键 -- `Ctrl+E E` -是否扩展编辑区域。 -- `Ctrl+Alt+N` -在当前文件夹下新建笔记。 -- `Ctrl+F` -页内查找和替换。 -- `Ctrl+Q` -退出VNote。 -- `Ctrl+J`/`Ctrl+K` -在笔记本列表、文件夹列表、笔记列表、已打开笔记列表和大纲目录中,均支持`Ctrl+J`和`Ctrl+K`导航。 -- `Ctrl+Left Mouse` -任意滚动。 -- `Ctrl+Shift+T` -恢复上一个关闭的文件。 -- `Ctrl+Alt+L` -打开灵犀页。 - -### 阅读模式 -- `Ctrl+W` -编辑当前笔记。 -- `H`/`J`/`K`/`L` -导航,对应于左/下/上/右方向键。 -- `Ctrl+U` -向上滚动半屏。 -- `Ctrl+D` -向下滚动半屏。 -- `gg`/`G` -跳转到笔记的开始或结尾。(区分大小写)。 -- `Ctrl + +/-` -放大/缩小页面。 -- `Ctrl+Wheel` -鼠标滚轮实现放大/缩小页面。 -- `Ctrl+0` -恢复页面大小为100%。 -- 标题跳转 - - `[[`:跳转到上一个标题; - - `]]`: 跳转到下一个标题; - - `[]`:跳转到上一个同层级的标题; - - `][`:跳转到下一个同层级的标题; - - `[{`:跳转到上一个高一层级的标题; - - `]}`:跳转到下一个高一层级的标题; - -### 编辑模式 -- `Ctrl+S` -保存当前更改。 -- `Ctrl+T` -保存当前更改并退出编辑模式。 - -#### 文本编辑 -- `Ctrl+B` -插入粗体;再次按`Ctrl+B`退出。如果已经选择文本,则将当前选择文本加粗。 -- `Ctrl+I` -插入斜体;再次按`Ctrl+I`退出。如果已经选择文本,则将当前选择文本改为斜体。 -- `Ctrl+D` -插入删除线;再次按`Ctrl+D`退出。如果已经选择文本,则将当前选择文本改为删除线。 -- `Ctrl+K` -插入行内代码;再次按`Ctrl+K`退出。如果已经选择文本,则将当前选择文本改为行内代码。 -- `Ctrl+M` -插入代码块;再次按`Ctrl+M`退出。如果已经选择文本,则将当前选择文本嵌入到代码块中。 -- `Ctrl+L` -插入链接。 -- `Ctrl+'` -插入图片。 -- `Ctrl+H` -退格键,向前删除一个字符。 -- `Ctrl+W` -删除光标位置向后到第一个空白字符之间的所有字符。 -- `Ctrl+U` -删除光标位置到行首的所有字符。 -- `Ctrl+` -插入级别为``的标题。``应该是1到6的一个数字。如果已经选择文本,则将当前选择文本改为标题。 -- `Ctrl+7` -删除当前行或所选择文本的标题标记。 -- `Tab`/`Shift+Tab` -增加或减小缩进。如果已经选择文本,则对所有选择的行进行缩进操作。 -- `Shift+Enter` -插入两个空格然后换行,在Markdown中类似于软换行的概念。 -- `Shift+Left`, `Shift+Right`, `Shift+Up`, `Shift+Down` -扩展选定左右一个字符,或上下一行。 -- `Ctrl+Shift+Left`, `Ctrl+Shift+Right` -扩展选定到单词开始或结尾。 -- `Ctrl+Shift+Up`, `Ctrl+Sfhit+Down` -扩展选定到段尾或段首。 -- `Shift+Home`, `Shift+End` -扩展选定到行首和行尾。 -- `Ctrl+Shift+Home`, `Ctrl+Shift+End` -扩展选定到笔记开始或结尾处。 - -## 自定义快捷键 -VNote支持自定义部分标准快捷键(但并不建议这么做)。VNote将快捷键信息保存在用户配置文件`vnote.ini`中的`[shortcuts]`和`[captain_mode_shortcuts]`两个小节。 - -例如,默认的配置可能是这样子的: - - -```ini -[shortcuts] -; Define shortcuts here, with each item in the form "operation=keysequence". -; Leave keysequence empty to disable the shortcut of an operation. -; Custom shortcuts may conflict with some key bindings in edit mode or Vim mode. -; Ctrl+Q is reserved for quitting VNote. - -; Leader key of Captain mode -CaptainMode=Ctrl+E -; Create a note in current folder -NewNote=Ctrl+Alt+N -; Save current note -SaveNote=Ctrl+S -; Save changes and enter read mode -SaveAndRead=Ctrl+T -; Edit current note -EditNote=Ctrl+W -; Close current note -CloseNote= -; Open file/replace dialog -Find=Ctrl+F -; Find next occurence -FindNext=F3 -; Find previous occurence -FindPrevious=Shift+F3 - -[captain_mode_shortcuts] -; Define shortcuts in Captain mode here. -; There shortcuts are the sub-sequence after the CaptainMode key sequence -; in [shortcuts]. - -; Enter Navigation mode -NavigationMode=W -; Show attachment list of current note -AttachmentList=A -; Locate to the folder of current note -LocateCurrentFile=D -; Toggle Expand mode -ExpandMode=E -; Alternate one/two panels view -OnePanelView=P -; Discard changes and enter read mode -DiscardAndRead=Q -; Toggle Tools dock widget -ToolsDock=T -; Close current note -CloseNote=X -; Show shortcuts help document -ShortcutsHelp=? -; Flush the log file -FlushLogFile=";" -; Show opened files list -OpenedFileList=F -; Activate the ith tab -ActivateTab1=1 -ActivateTab2=2 -ActivateTab3=3 -ActivateTab4=4 -ActivateTab5=5 -ActivateTab6=6 -ActivateTab7=7 -ActivateTab8=8 -ActivateTab9=9 -; Alternate between current and last tab -AlternateTab=0 -; Activate next tab -ActivateNextTab=J -; Activate previous tab -ActivatePreviousTab=K -; Activate the window split on the left -ActivateSplitLeft=H -; Activate the window split on the right -ActivateSplitRight=L -; Move current tab one split left -MoveTabSplitLeft=Shift+H -; Move current tab one split right -MoveTabSplitRight=Shift+L -; Create a vertical split -VerticalSplit=V -; Remove current split -RemoveSplit=R -``` - -每一项配置的形式为`操作=按键序列`。如果`按键序列`为空,则表示禁用该操作的快捷键。 - -注意,`Ctrl+Q`保留为退出VNote。 - -# 舰长模式 -为了更有效地利用快捷键,VNote支持 **舰长模式**。 - -按前导键`Ctrl+E`后,VNote会进入舰长模式。在舰长模式中,VNote会支持更多高效的快捷操作。 - -- `E` -是否扩展编辑区域。 -- `P` -切换单列/双列面板模式。 -- `T` -打开或关闭工具面板。 -- `F` -打开当前分割窗口的笔记列表。在该列表中,可以直接按笔记对应的序号实现跳转。 -- `A` -打开当前笔记的附件列表。 -- `X` -关闭当前标签页。 -- `J` -跳转到下一个标签页。 -- `K` -跳转到上一个标签页。 -- `1` - `9` -数字1到9会跳转到对应序号的标签页。 -- `0` -跳转到前一个标签页(即前一个当前标签页)。实现当前标签页和前一个标签页之间的轮换。 -- `D` -定位当前笔记所在文件夹。 -- `Q` -放弃当前更改并退出编辑模式。 -- `V` -垂直分割当前窗口。 -- `R` -移除当前分割窗口。 -- `H` -跳转到左边一个分割窗口。 -- `L` -跳转到右边一个分割窗口。 -- `Shift+H` -将当前标签页左移一个分割窗口。 -- `Shift+L` -将当前标签页右移一个分割窗口。 -- `M` -编辑模式中,将当前光标所在词或者所选文本进行幻词解析。 -- `S` -在编辑模式中应用片段。 -- `?` -显示本快捷键说明。 - -## 展览模式 -在舰长模式中,`W`命令会进入 **展览模式**。在展览模式中,VNote会在常用的主要部件上显示至多两个字母,此时输入对应的字母即可跳转到该部件中,从而实现快速切换焦点并触发功能。 - -# Vim Mode -VNote支持一个简单但有用的Vim模式,包括 **正常**, **插入**, **可视**, **可视行** 模式。 - -VNote支持以下几个Vim的特性: - -- `r`, `s`, `S`, `i`, `I`, `a`, `A`, `c`, `C`, `o`, `O`; -- 操作 `d`, `c`, `y`, `p`, `<`, `>`, `gu`, `gU`, `J`, `gJ`, `~`; -- 移动 `h/j/k/l`, `gj/gk/g0`, `Ctrl+U`, `Ctrl+D`, `gg`, `G`, `0`, `^`, `{`, `}`, `$`; -- 标记 `a-z`; -- 寄存器 `"`, `_`, `+`, `a-z`(`A-Z`); -- 跳转位置列表 (`Ctrl+O` and `Ctrl+I`); -- 前导键 (`Space`) - - 目前 `y/d/p` 等同于 `"+y/d/p`, 从而可以访问系统剪切板; - - `` 清除查找高亮; - - `w` 保存笔记; -- `zz`, `zb`, `zt`; -- `u` 和 `Ctrl+R` 撤销和重做; -- 文本对象 `i/a`:word, WORD, `''`, `""`, `` ` ` ``, `()`, `[]`, `<>`, `{}`; -- 命令行 `:w`, `:wq`, `:x`, `:q`, `:q!`, `:nohlsearch`; -- 标题跳转 - - `[[`:跳转到上一个标题; - - `]]`: 跳转到下一个标题; - - `[]`:跳转到上一个同层级的标题; - - `][`:跳转到下一个同层级的标题; - - `[{`:跳转到上一个高一层级的标题; - - `]}`:跳转到下一个高一层级的标题; -- `/` 和 `?` 开始查找 - - `n` 和 `N` 查找下一处或上一处; - - `Ctrl+N` 和 `Ctrl+P` 浏览查找历史; -- `Ctrl+R` 读取指定寄存器的值; -- `Ctrl+O` 在插入模式中临时切换为正常模式; - -VNote目前暂时不支持Vim的宏和重复(`.`)特性。 - -在VNote上享受Vim的美好时光吧! diff --git a/src/resources/hoedown.js b/src/resources/hoedown.js deleted file mode 100644 index 80e253c0..00000000 --- a/src/resources/hoedown.js +++ /dev/null @@ -1,71 +0,0 @@ -var placeholder = document.getElementById('placeholder'); - -// Use Marked to highlight code blocks in edit mode. -marked.setOptions({ - highlight: function(code, lang) { - if (lang) { - if (hljs.getLanguage(lang)) { - return hljs.highlight(lang, code).value; - } else { - return hljs.highlightAuto(code).value; - } - } else { - return code; - } - } -}); - -var updateHtml = function(html) { - placeholder.innerHTML = html; - - insertImageCaption(); - - var codes = document.getElementsByTagName('code'); - mermaidIdx = 0; - for (var i = 0; i < codes.length; ++i) { - var code = codes[i]; - if (code.parentElement.tagName.toLowerCase() == 'pre') { - if (VEnableMermaid && code.classList.contains('language-mermaid')) { - // Mermaid code block. - if (renderMermaidOne(code)) { - // replaceChild() will decrease codes.length. - --i; - continue; - } - } else if (VEnableFlowchart && code.classList.contains('language-flowchart')) { - // Flowchart code block. - if (renderFlowchartOne(code)) { - // replaceChild() will decrease codes.length. - --i; - continue; - } - } - - if (listContainsRegex(code.classList, /language-.*/)) { - hljs.highlightBlock(code); - } - } - } - - addClassToCodeBlock(); - renderCodeBlockLineNumber(); - - // If you add new logics after handling MathJax, please pay attention to - // finishLoading logic. - // MathJax may be not loaded for now. - if (VEnableMathjax && (typeof MathJax != "undefined")) { - try { - MathJax.Hub.Queue(["Typeset", MathJax.Hub, placeholder, finishLogics]); - } catch (err) { - content.setLog("err: " + err); - finishLogics(); - } - } else { - finishLogics(); - } -}; - -var highlightText = function(text, id, timeStamp) { - var html = marked(text); - content.highlightTextCB(html, id, timeStamp); -} diff --git a/src/resources/icons/128x128/vnote.png b/src/resources/icons/128x128/vnote.png deleted file mode 100644 index d325b223..00000000 Binary files a/src/resources/icons/128x128/vnote.png and /dev/null differ diff --git a/src/resources/icons/16x16/vnote.png b/src/resources/icons/16x16/vnote.png deleted file mode 100644 index 184b5bf7..00000000 Binary files a/src/resources/icons/16x16/vnote.png and /dev/null differ diff --git a/src/resources/icons/256x256/vnote.png b/src/resources/icons/256x256/vnote.png deleted file mode 100644 index 69fee17d..00000000 Binary files a/src/resources/icons/256x256/vnote.png and /dev/null differ diff --git a/src/resources/icons/32x32/vnote.png b/src/resources/icons/32x32/vnote.png deleted file mode 100644 index 155456b5..00000000 Binary files a/src/resources/icons/32x32/vnote.png and /dev/null differ diff --git a/src/resources/icons/48x48/vnote.png b/src/resources/icons/48x48/vnote.png deleted file mode 100644 index d6d9a156..00000000 Binary files a/src/resources/icons/48x48/vnote.png and /dev/null differ diff --git a/src/resources/icons/64x64/vnote.png b/src/resources/icons/64x64/vnote.png deleted file mode 100644 index e889ca0e..00000000 Binary files a/src/resources/icons/64x64/vnote.png and /dev/null differ diff --git a/src/resources/icons/add_attachment.svg b/src/resources/icons/add_attachment.svg deleted file mode 100644 index b9e8f00d..00000000 --- a/src/resources/icons/add_attachment.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/src/resources/icons/add_snippet.svg b/src/resources/icons/add_snippet.svg deleted file mode 100644 index b9e8f00d..00000000 --- a/src/resources/icons/add_snippet.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/src/resources/icons/apply_snippet.svg b/src/resources/icons/apply_snippet.svg deleted file mode 100644 index a1a3b6ef..00000000 --- a/src/resources/icons/apply_snippet.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/resources/icons/attachment.svg b/src/resources/icons/attachment.svg deleted file mode 100644 index 8b7b4ed5..00000000 --- a/src/resources/icons/attachment.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - diff --git a/src/resources/icons/bold.svg b/src/resources/icons/bold.svg deleted file mode 100644 index 43af6765..00000000 --- a/src/resources/icons/bold.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - Layer 1 - B - - diff --git a/src/resources/icons/clear_attachment.svg b/src/resources/icons/clear_attachment.svg deleted file mode 100644 index 59af5e14..00000000 --- a/src/resources/icons/clear_attachment.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/close.svg b/src/resources/icons/close.svg deleted file mode 100644 index ce23b83e..00000000 --- a/src/resources/icons/close.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/close_note_tb.svg b/src/resources/icons/close_note_tb.svg deleted file mode 100644 index ce23b83e..00000000 --- a/src/resources/icons/close_note_tb.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/close_red.svg b/src/resources/icons/close_red.svg deleted file mode 100644 index 3f300f1c..00000000 --- a/src/resources/icons/close_red.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/code_block.svg b/src/resources/icons/code_block.svg deleted file mode 100644 index 2f8ce405..00000000 --- a/src/resources/icons/code_block.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - # - - diff --git a/src/resources/icons/compact_mode.svg b/src/resources/icons/compact_mode.svg deleted file mode 100644 index 6cc49aa2..00000000 --- a/src/resources/icons/compact_mode.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - one_panel - - Layer 1 - - - - - diff --git a/src/resources/icons/copy.svg b/src/resources/icons/copy.svg deleted file mode 100644 index 7ababcd8..00000000 --- a/src/resources/icons/copy.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/corner_menu.svg b/src/resources/icons/corner_menu.svg deleted file mode 100644 index f7202eaa..00000000 --- a/src/resources/icons/corner_menu.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/resources/icons/corner_menu_cur.svg b/src/resources/icons/corner_menu_cur.svg deleted file mode 100644 index e290311b..00000000 --- a/src/resources/icons/corner_menu_cur.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/resources/icons/corner_tablist.svg b/src/resources/icons/corner_tablist.svg deleted file mode 100644 index b20efa2c..00000000 --- a/src/resources/icons/corner_tablist.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - diff --git a/src/resources/icons/corner_tablist_cur.svg b/src/resources/icons/corner_tablist_cur.svg deleted file mode 100644 index 4a2770b2..00000000 --- a/src/resources/icons/corner_tablist_cur.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - diff --git a/src/resources/icons/create_note.svg b/src/resources/icons/create_note.svg deleted file mode 100644 index 689eeeed..00000000 --- a/src/resources/icons/create_note.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/src/resources/icons/create_note_tb.svg b/src/resources/icons/create_note_tb.svg deleted file mode 100644 index 411ae214..00000000 --- a/src/resources/icons/create_note_tb.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/create_notebook.svg b/src/resources/icons/create_notebook.svg deleted file mode 100644 index 689eeeed..00000000 --- a/src/resources/icons/create_notebook.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/src/resources/icons/create_rootdir.svg b/src/resources/icons/create_rootdir.svg deleted file mode 100644 index 689eeeed..00000000 --- a/src/resources/icons/create_rootdir.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/src/resources/icons/create_rootdir_tb.svg b/src/resources/icons/create_rootdir_tb.svg deleted file mode 100644 index 672e65f5..00000000 --- a/src/resources/icons/create_rootdir_tb.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/create_subdir.svg b/src/resources/icons/create_subdir.svg deleted file mode 100644 index cde438a1..00000000 --- a/src/resources/icons/create_subdir.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - Layer 1 - - - - - - diff --git a/src/resources/icons/cut.svg b/src/resources/icons/cut.svg deleted file mode 100644 index 58c392ed..00000000 --- a/src/resources/icons/cut.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - diff --git a/src/resources/icons/delete_attachment.svg b/src/resources/icons/delete_attachment.svg deleted file mode 100644 index 382a85ce..00000000 --- a/src/resources/icons/delete_attachment.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/delete_dir.svg b/src/resources/icons/delete_dir.svg deleted file mode 100644 index 366b12cc..00000000 --- a/src/resources/icons/delete_dir.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/delete_note.svg b/src/resources/icons/delete_note.svg deleted file mode 100644 index 366b12cc..00000000 --- a/src/resources/icons/delete_note.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/delete_note_tb.svg b/src/resources/icons/delete_note_tb.svg deleted file mode 100644 index e875331f..00000000 --- a/src/resources/icons/delete_note_tb.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/delete_notebook.svg b/src/resources/icons/delete_notebook.svg deleted file mode 100644 index 366b12cc..00000000 --- a/src/resources/icons/delete_notebook.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/delete_snippet.svg b/src/resources/icons/delete_snippet.svg deleted file mode 100644 index 382a85ce..00000000 --- a/src/resources/icons/delete_snippet.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/dir_info.svg b/src/resources/icons/dir_info.svg deleted file mode 100644 index a9ea538a..00000000 --- a/src/resources/icons/dir_info.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/dir_item.svg b/src/resources/icons/dir_item.svg deleted file mode 100644 index 672e65f5..00000000 --- a/src/resources/icons/dir_item.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/discard_exit.svg b/src/resources/icons/discard_exit.svg deleted file mode 100644 index 7cc62972..00000000 --- a/src/resources/icons/discard_exit.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/resources/icons/edit_note.svg b/src/resources/icons/edit_note.svg deleted file mode 100644 index c4283b86..00000000 --- a/src/resources/icons/edit_note.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - diff --git a/src/resources/icons/editing.svg b/src/resources/icons/editing.svg deleted file mode 100644 index 05fd34cc..00000000 --- a/src/resources/icons/editing.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/icons/editing_modified.svg b/src/resources/icons/editing_modified.svg deleted file mode 100644 index 9ae66550..00000000 --- a/src/resources/icons/editing_modified.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/icons/empty_recycle_bin.svg b/src/resources/icons/empty_recycle_bin.svg deleted file mode 100644 index a2200617..00000000 --- a/src/resources/icons/empty_recycle_bin.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - Layer 1 - - - - Layer 1 copy - - diff --git a/src/resources/icons/expand.svg b/src/resources/icons/expand.svg deleted file mode 100644 index 53ed9a2f..00000000 --- a/src/resources/icons/expand.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/icons/find_replace.svg b/src/resources/icons/find_replace.svg deleted file mode 100644 index c3f6bf6f..00000000 --- a/src/resources/icons/find_replace.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/flash_page.svg b/src/resources/icons/flash_page.svg deleted file mode 100644 index 555ed2c3..00000000 --- a/src/resources/icons/flash_page.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/icons/heading.svg b/src/resources/icons/heading.svg deleted file mode 100644 index d6c3f9d7..00000000 --- a/src/resources/icons/heading.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - Layer 1 - H - - diff --git a/src/resources/icons/heading_sequence.svg b/src/resources/icons/heading_sequence.svg deleted file mode 100644 index b8014ac6..00000000 --- a/src/resources/icons/heading_sequence.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - Layer 2 - 1.2. - - diff --git a/src/resources/icons/import_note.svg b/src/resources/icons/import_note.svg deleted file mode 100644 index b7e13b74..00000000 --- a/src/resources/icons/import_note.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - diff --git a/src/resources/icons/inline_code.svg b/src/resources/icons/inline_code.svg deleted file mode 100644 index ea166774..00000000 --- a/src/resources/icons/inline_code.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - Layer 1 - K - - diff --git a/src/resources/icons/insert_image.svg b/src/resources/icons/insert_image.svg deleted file mode 100644 index d981d7ce..00000000 --- a/src/resources/icons/insert_image.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/italic.svg b/src/resources/icons/italic.svg deleted file mode 100644 index da96923d..00000000 --- a/src/resources/icons/italic.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - Layer 1 - I - - \ No newline at end of file diff --git a/src/resources/icons/link.svg b/src/resources/icons/link.svg deleted file mode 100644 index 81802452..00000000 --- a/src/resources/icons/link.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - diff --git a/src/resources/icons/locate_attachment.svg b/src/resources/icons/locate_attachment.svg deleted file mode 100644 index ce387636..00000000 --- a/src/resources/icons/locate_attachment.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/locate_note.svg b/src/resources/icons/locate_note.svg deleted file mode 100644 index 45fe23e7..00000000 --- a/src/resources/icons/locate_note.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - diff --git a/src/resources/icons/locate_snippet.svg b/src/resources/icons/locate_snippet.svg deleted file mode 100644 index ce387636..00000000 --- a/src/resources/icons/locate_snippet.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/manage_template.svg b/src/resources/icons/manage_template.svg deleted file mode 100644 index ce387636..00000000 --- a/src/resources/icons/manage_template.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/move_tab_left.svg b/src/resources/icons/move_tab_left.svg deleted file mode 100644 index e87c7333..00000000 --- a/src/resources/icons/move_tab_left.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/resources/icons/move_tab_right.svg b/src/resources/icons/move_tab_right.svg deleted file mode 100644 index 403d203b..00000000 --- a/src/resources/icons/move_tab_right.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/resources/icons/note_info.svg b/src/resources/icons/note_info.svg deleted file mode 100644 index a9ea538a..00000000 --- a/src/resources/icons/note_info.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/note_info_tb.svg b/src/resources/icons/note_info_tb.svg deleted file mode 100644 index a9ea538a..00000000 --- a/src/resources/icons/note_info_tb.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/notebook_info.svg b/src/resources/icons/notebook_info.svg deleted file mode 100644 index a9ea538a..00000000 --- a/src/resources/icons/notebook_info.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/notebook_item.svg b/src/resources/icons/notebook_item.svg deleted file mode 100644 index eff98dc8..00000000 --- a/src/resources/icons/notebook_item.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - diff --git a/src/resources/icons/one_panel.svg b/src/resources/icons/one_panel.svg deleted file mode 100644 index 2b8f3ffb..00000000 --- a/src/resources/icons/one_panel.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - one_panel - - Layer 1 - - - - \ No newline at end of file diff --git a/src/resources/icons/outline.svg b/src/resources/icons/outline.svg deleted file mode 100644 index 085bc67c..00000000 --- a/src/resources/icons/outline.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/resources/icons/paste.svg b/src/resources/icons/paste.svg deleted file mode 100644 index 80d8a17d..00000000 --- a/src/resources/icons/paste.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/print.svg b/src/resources/icons/print.svg deleted file mode 100644 index 6d355bf7..00000000 --- a/src/resources/icons/print.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/icons/reading.svg b/src/resources/icons/reading.svg deleted file mode 100644 index 04a767b2..00000000 --- a/src/resources/icons/reading.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - diff --git a/src/resources/icons/reading_modified.svg b/src/resources/icons/reading_modified.svg deleted file mode 100644 index 217b2c30..00000000 --- a/src/resources/icons/reading_modified.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - diff --git a/src/resources/icons/recycle_bin.svg b/src/resources/icons/recycle_bin.svg deleted file mode 100644 index 88730b7d..00000000 --- a/src/resources/icons/recycle_bin.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - Layer 1 - - - - Layer 1 copy - - - diff --git a/src/resources/icons/remove_split.svg b/src/resources/icons/remove_split.svg deleted file mode 100644 index fdc83bd6..00000000 --- a/src/resources/icons/remove_split.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/save_exit.svg b/src/resources/icons/save_exit.svg deleted file mode 100644 index 357d3026..00000000 --- a/src/resources/icons/save_exit.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/save_note.svg b/src/resources/icons/save_note.svg deleted file mode 100644 index 1e43c853..00000000 --- a/src/resources/icons/save_note.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - Layer 1 - - - - - - - - - - - \ No newline at end of file diff --git a/src/resources/icons/search_wrap.svg b/src/resources/icons/search_wrap.svg deleted file mode 100644 index 984bd7b7..00000000 --- a/src/resources/icons/search_wrap.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - diff --git a/src/resources/icons/settings.svg b/src/resources/icons/settings.svg deleted file mode 100644 index 913c2a7d..00000000 --- a/src/resources/icons/settings.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - diff --git a/src/resources/icons/snippet_info.svg b/src/resources/icons/snippet_info.svg deleted file mode 100644 index 768fefeb..00000000 --- a/src/resources/icons/snippet_info.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/snippets.svg b/src/resources/icons/snippets.svg deleted file mode 100644 index 42d9b616..00000000 --- a/src/resources/icons/snippets.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/resources/icons/sort.svg b/src/resources/icons/sort.svg deleted file mode 100644 index 9dcee9ac..00000000 --- a/src/resources/icons/sort.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - Layer 2 - A - Z - - diff --git a/src/resources/icons/split_window.svg b/src/resources/icons/split_window.svg deleted file mode 100644 index b778bb9f..00000000 --- a/src/resources/icons/split_window.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/resources/icons/strikethrough.svg b/src/resources/icons/strikethrough.svg deleted file mode 100644 index d44defe2..00000000 --- a/src/resources/icons/strikethrough.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - Layer 1 - D - - - diff --git a/src/resources/icons/two_panels.svg b/src/resources/icons/two_panels.svg deleted file mode 100644 index 7e9757bb..00000000 --- a/src/resources/icons/two_panels.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - one_panel - - Layer 1 - - - - - \ No newline at end of file diff --git a/src/resources/icons/vnote.icns b/src/resources/icons/vnote.icns deleted file mode 100644 index 5635a216..00000000 Binary files a/src/resources/icons/vnote.icns and /dev/null differ diff --git a/src/resources/icons/vnote.ico b/src/resources/icons/vnote.ico deleted file mode 100644 index a196a1a6..00000000 Binary files a/src/resources/icons/vnote.ico and /dev/null differ diff --git a/src/resources/icons/vnote.png b/src/resources/icons/vnote.png deleted file mode 100644 index 2c1ecb69..00000000 Binary files a/src/resources/icons/vnote.png and /dev/null differ diff --git a/src/resources/icons/vnote.svg b/src/resources/icons/vnote.svg deleted file mode 100644 index 8cd2fb03..00000000 --- a/src/resources/icons/vnote.svg +++ /dev/null @@ -1 +0,0 @@ -vnote diff --git a/src/resources/icons/vnote_update.png b/src/resources/icons/vnote_update.png deleted file mode 100644 index 8e7b3f9c..00000000 Binary files a/src/resources/icons/vnote_update.png and /dev/null differ diff --git a/src/resources/icons/vnote_update.svg b/src/resources/icons/vnote_update.svg deleted file mode 100644 index 54bc77cf..00000000 --- a/src/resources/icons/vnote_update.svg +++ /dev/null @@ -1 +0,0 @@ -vnote_cube diff --git a/src/resources/markdown-it.js b/src/resources/markdown-it.js deleted file mode 100644 index b3055cd2..00000000 --- a/src/resources/markdown-it.js +++ /dev/null @@ -1,126 +0,0 @@ -var placeholder = document.getElementById('placeholder'); -var nameCounter = 0; -var toc = []; // Table of Content as a list - -var getHeadingLevel = function(h) { - var level = 1; - switch (h) { - case 'h1': - break; - - case 'h2': - level += 1; - break; - - case 'h3': - level += 2; - break; - - case 'h4': - level += 3; - break; - - case 'h5': - level += 4; - break; - - case 'h6': - level += 5; - break; - - default: - level += 6; - break; - } - return level; -} - -// There is a VMarkdownitOption struct passed in. -// var VMarkdownitOption = { html, breaks, linkify }; -var mdit = window.markdownit({ - html: VMarkdownitOption.html, - breaks: VMarkdownitOption.breaks, - linkify: VMarkdownitOption.linkify, - typographer: true, - langPrefix: 'lang-', - highlight: function(str, lang) { - if (lang) { - if (hljs.getLanguage(lang)) { - return hljs.highlight(lang, str).value; - } else { - return hljs.highlightAuto(str).value; - } - } else { - // Use external default escaping. - return ''; - } - } -}); - -mdit = mdit.use(window.markdownitHeadingAnchor, { - anchorClass: 'vnote-anchor', - addHeadingID: true, - addHeadingAnchor: true, - slugify: function(md, s) { - return 'toc_' + nameCounter++; - }, - headingHook: function(openToken, inlineToken, anchor) { - toc.push({ - level: getHeadingLevel(openToken.tag), - anchor: anchor, - title: mdit.utils.escapeHtml(inlineToken.content) - }); - } -}); - -mdit = mdit.use(window.markdownitTaskLists); -mdit = mdit.use(window.markdownitSub); -mdit = mdit.use(window.markdownitSup); -mdit = mdit.use(window.markdownitFootnote); - -var mdHasTocSection = function(markdown) { - var n = markdown.search(/(\n|^)\[toc\]/i); - return n != -1; -}; - -var markdownToHtml = function(markdown, needToc) { - toc = []; - nameCounter = 0; - var html = mdit.render(markdown); - if (needToc) { - return html.replace(/

\[TOC\]<\/p>/ig, '

'); - } else { - return html; - } -}; - -var updateText = function(text) { - var needToc = mdHasTocSection(text); - var html = markdownToHtml(text, needToc); - placeholder.innerHTML = html; - handleToc(needToc); - insertImageCaption(); - renderMermaid('lang-mermaid'); - renderFlowchart('lang-flowchart'); - addClassToCodeBlock(); - renderCodeBlockLineNumber(); - - // If you add new logics after handling MathJax, please pay attention to - // finishLoading logic. - if (VEnableMathjax) { - try { - MathJax.Hub.Queue(["Typeset", MathJax.Hub, placeholder, finishLogics]); - } catch (err) { - content.setLog("err: " + err); - finishLogics(); - } - } else { - finishLogics(); - } -}; - -var highlightText = function(text, id, timeStamp) { - var html = mdit.render(text); - content.highlightTextCB(html, id, timeStamp); -} - diff --git a/src/resources/markdown_template.html b/src/resources/markdown_template.html deleted file mode 100644 index 4dd4a332..00000000 --- a/src/resources/markdown_template.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - -
- - diff --git a/src/resources/markdown_template.js b/src/resources/markdown_template.js deleted file mode 100644 index 4c3dbf50..00000000 --- a/src/resources/markdown_template.js +++ /dev/null @@ -1,856 +0,0 @@ -var content; - -// Current header index in all headers. -var currentHeaderIdx = -1; - -// Pending keys for keydown. -var pendingKeys = []; - -var VMermaidDivClass = 'mermaid-diagram'; -var VFlowchartDivClass = 'flowchart-diagram'; -if (typeof VEnableMermaid == 'undefined') { - VEnableMermaid = false; -} else if (VEnableMermaid) { - mermaidAPI.initialize({ - startOnLoad: false - }); -} - -if (typeof VEnableFlowchart == 'undefined') { - VEnableFlowchart = false; -} - -if (typeof VEnableMathjax == 'undefined') { - VEnableMathjax = false; -} - -if (typeof VEnableHighlightLineNumber == 'undefined') { - VEnableHighlightLineNumber = false; -} - -// Add a caption (using alt text) under the image. -var VImageCenterClass = 'img-center'; -var VImageCaptionClass = 'img-caption'; -var VImagePackageClass = 'img-package'; -if (typeof VEnableImageCaption == 'undefined') { - VEnableImageCaption = false; -} - -new QWebChannel(qt.webChannelTransport, - function(channel) { - content = channel.objects.content; - if (typeof updateHtml == "function") { - updateHtml(content.html); - content.htmlChanged.connect(updateHtml); - } - if (typeof updateText == "function") { - content.textChanged.connect(updateText); - content.updateText(); - } - content.requestScrollToAnchor.connect(scrollToAnchor); - - if (typeof highlightText == "function") { - content.requestHighlightText.connect(highlightText); - content.noticeReadyToHighlightText(); - } - }); - -var VHighlightedAnchorClass = 'highlighted-anchor'; - -var clearHighlightedAnchor = function() { - var headers = document.getElementsByClassName(VHighlightedAnchorClass); - while (headers.length > 0) { - headers[0].classList.remove(VHighlightedAnchorClass); - } -}; - -var highlightAnchor = function(anchor) { - clearHighlightedAnchor(); - anchor.classList.add(VHighlightedAnchorClass); -}; - -var g_muteScroll = false; - -var scrollToAnchor = function(anchor) { - g_muteScroll = true; - currentHeaderIdx = -1; - if (!anchor) { - window.scrollTo(0, 0); - g_muteScroll = false; - return; - } - - var anc = document.getElementById(anchor); - if (anc != null) { - anc.scrollIntoView(); - highlightAnchor(anc); - - var headers = document.querySelectorAll("h1, h2, h3, h4, h5, h6"); - for (var i = 0; i < headers.length; ++i) { - if (headers[i] == anc) { - currentHeaderIdx = i; - break; - } - } - } - - // Disable scroll temporarily. - setTimeout("g_muteScroll = false", 100); -}; - -window.onwheel = function(e) { - e = e || window.event; - var ctrl = !!e.ctrlKey; - if (ctrl) { - e.preventDefault(); - } -} - -window.onscroll = function() { - if (g_muteScroll) { - return; - } - - currentHeaderIdx = -1; - var scrollTop = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset; - var eles = document.querySelectorAll("h1, h2, h3, h4, h5, h6"); - - if (eles.length == 0) { - content.setHeader(""); - return; - } - - var biaScrollTop = scrollTop + 50; - for (var i = 0; i < eles.length; ++i) { - if (biaScrollTop >= eles[i].offsetTop) { - currentHeaderIdx = i; - } else { - break; - } - } - - var curHeader = null; - if (currentHeaderIdx != -1) { - curHeader = eles[currentHeaderIdx].getAttribute("id"); - } - - content.setHeader(curHeader ? curHeader : ""); -}; - -document.onkeydown = function(e) { - // Need to clear pending kyes. - var clear = true; - - // This even has been handled completely. No need to call the default handler. - var accept = true; - - e = e || window.event; - var key; - var shift; - var ctrl; - if (e.which) { - key = e.which; - } else { - key = e.keyCode; - } - - shift = !!e.shiftKey; - ctrl = !!e.ctrlKey; - switch (key) { - // Skip Ctrl, Shift, Alt, Supper. - case 16: - case 17: - case 18: - case 91: - clear = false; - break; - - case 74: // J - window.scrollBy(0, 100); - break; - - case 75: // K - window.scrollBy(0, -100); - break; - - case 72: // H - window.scrollBy(-100, 0); - break; - - case 76: // L - window.scrollBy(100, 0); - break; - - case 71: // G - if (shift) { - if (pendingKeys.length == 0) { - var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft || window.pageXOffset; - var scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight; - window.scrollTo(scrollLeft, scrollHeight); - break; - } - } else { - if (pendingKeys.length == 0) { - // First g, pend it. - pendingKeys.push({ - key: key, - ctrl: ctrl, - shift: shift - }); - - clear = false; - break; - } else if (pendingKeys.length == 1) { - var pendKey = pendingKeys[0]; - if (pendKey.key == key && !pendKey.shift && !pendKey.ctrl) { - var scrollLeft = document.documentElement.scrollLeft - || document.body.scrollLeft - || window.pageXOffset; - window.scrollTo(scrollLeft, 0); - break; - } - } - } - - accept = false; - break; - - case 85: // U - if (ctrl) { - var clientHeight = document.documentElement.clientHeight; - window.scrollBy(0, -clientHeight / 2); - break; - } - - accept = false; - break; - - case 68: // D - if (ctrl) { - var clientHeight = document.documentElement.clientHeight; - window.scrollBy(0, clientHeight / 2); - break; - } - - accept = false; - break; - - case 219: // [ or { - if (shift) { - // { - if (pendingKeys.length == 1) { - var pendKey = pendingKeys[0]; - if (pendKey.key == key && !pendKey.shift && !pendKey.ctrl) { - // [{, jump to previous title at a higher level. - jumpTitle(false, -1, 1); - break; - } - } - } else { - // [ - if (pendingKeys.length == 0) { - // First [, pend it. - pendingKeys.push({ - key: key, - ctrl: ctrl, - shift: shift - }); - - clear = false; - break; - } else if (pendingKeys.length == 1) { - var pendKey = pendingKeys[0]; - if (pendKey.key == key && !pendKey.shift && !pendKey.ctrl) { - // [[, jump to previous title. - jumpTitle(false, 1, 1); - break; - } else if (pendKey.key == 221 && !pendKey.shift && !pendKey.ctrl) { - // ][, jump to next title at the same level. - jumpTitle(true, 0, 1); - break; - } - } - } - - accept = false; - break; - - case 221: // ] or } - if (shift) { - // } - if (pendingKeys.length == 1) { - var pendKey = pendingKeys[0]; - if (pendKey.key == key && !pendKey.shift && !pendKey.ctrl) { - // ]}, jump to next title at a higher level. - jumpTitle(true, -1, 1); - break; - } - } - } else { - // ] - if (pendingKeys.length == 0) { - // First ], pend it. - pendingKeys.push({ - key: key, - ctrl: ctrl, - shift: shift - }); - - clear = false; - break; - } else if (pendingKeys.length == 1) { - var pendKey = pendingKeys[0]; - if (pendKey.key == key && !pendKey.shift && !pendKey.ctrl) { - // ]], jump to next title. - jumpTitle(true, 1, 1); - break; - } else if (pendKey.key == 219 && !pendKey.shift && !pendKey.ctrl) { - // [], jump to previous title at the same level. - jumpTitle(false, 0, 1); - break; - } - } - } - - accept = false; - break; - - default: - accept = false; - break; - } - - if (clear) { - pendingKeys = []; - } - - if (accept) { - e.preventDefault(); - } else { - content.keyPressEvent(key, ctrl, shift); - } -}; - -var mermaidParserErr = false; -var mermaidIdx = 0; - -if (VEnableMermaid) { - mermaidAPI.parseError = function(err, hash) { - content.setLog("err: " + err); - mermaidParserErr = true; - - // Clean the container element, or mermaidAPI won't render the graph with - // the same id. - var errGraph = document.getElementById('mermaid-diagram-' + mermaidIdx); - var parentNode = errGraph.parentElement; - parentNode.outerHTML = ''; - delete parentNode; - }; -} - -// @className, the class name of the mermaid code block, such as 'lang-mermaid'. -var renderMermaid = function(className) { - if (!VEnableMermaid) { - return; - } - - var codes = document.getElementsByTagName('code'); - mermaidIdx = 0; - for (var i = 0; i < codes.length; ++i) { - var code = codes[i]; - if (code.classList.contains(className)) { - if (renderMermaidOne(code)) { - // replaceChild() will decrease codes.length. - --i; - } - } - } -}; - -// Render @code as Mermaid graph. -// Returns true if succeeded. -var renderMermaidOne = function(code) { - // Mermaid code block. - mermaidParserErr = false; - mermaidIdx++; - try { - // Do not increment mermaidIdx here. - var graph = mermaidAPI.render('mermaid-diagram-' + mermaidIdx, code.innerText, function(){}); - } catch (err) { - content.setLog("err: " + err); - return false; - } - - if (mermaidParserErr || typeof graph == "undefined") { - return false; - } - - var graphDiv = document.createElement('div'); - graphDiv.classList.add(VMermaidDivClass); - graphDiv.innerHTML = graph; - var preNode = code.parentNode; - preNode.classList.add(VMermaidDivClass); - preNode.replaceChild(graphDiv, code); - return true; -}; - -var flowchartIdx = 0; - -// @className, the class name of the flowchart code block, such as 'lang-flowchart'. -var renderFlowchart = function(className) { - if (!VEnableFlowchart) { - return; - } - - var codes = document.getElementsByTagName('code'); - flowchartIdx = 0; - for (var i = 0; i < codes.length; ++i) { - var code = codes[i]; - if (code.classList.contains(className)) { - if (renderFlowchartOne(code, flowchartIdx)) { - // replaceChild() will decrease codes.length. - --i; - } - } - } -}; - -// Render @code as Flowchart.js graph. -// Returns true if succeeded. -var renderFlowchartOne = function(code) { - // Flowchart code block. - flowchartIdx++; - try { - var graph = flowchart.parse(code.innerText); - } catch (err) { - content.setLog("err: " + err); - return false; - } - - if (typeof graph == "undefined") { - return false; - } - - var graphDiv = document.createElement('div'); - graphDiv.id = 'flowchart-diagram-' + flowchartIdx; - graphDiv.classList.add(VFlowchartDivClass); - var preNode = code.parentNode; - preNode.replaceChild(graphDiv, code); - - // Draw on it after adding it to page. - try { - graph.drawSVG(graphDiv.id); - } catch (err) { - content.setLog("err: " + err); - preNode.replaceChild(code, graphDiv); - delete graphDiv; - return false; - } - - preNode.classList.add(VMermaidDivClass); - return true; -}; - -var isImageBlock = function(img) { - var pn = img.parentNode; - return (pn.children.length == 1) && (pn.innerText == ''); -}; - -var isImageWithBr = function(img) { - var sibling = img.nextSibling; - while (sibling) { - if (sibling.nodeType == 8) { - // Comment node. - // Just continue. - sibling = sibling.nextSibling; - continue; - } else if (sibling.nodeType == 1) { - if (sibling.tagName == 'BR') { - break; - } - } - - return false; - } - - sibling = img.previousSibling; - while (sibling) { - if (sibling.nodeType == 8) { - // Comment node. - sibling = sibling.previousSibling; - continue; - } else if (sibling.nodeType == 1) { - // Element node. - if (sibling.tagName == 'BR') { - break; - } - } else if (sibling.nodeType == 3) { - // Text node. - if (sibling.nodeValue == '\n') { - var tmp = sibling.previousSibling; - if (tmp && tmp.tagName == 'BR') { - break; - } - } - } - - return false; - } - - return true; -}; - -var getImageType = function(img) { - var type = -1; - if (isImageBlock(img)) { - type = 0; - } else if (isImageWithBr(img)) { - type = 1; - } - - return type; -}; - -// Center the image block and insert the alt text as caption. -var insertImageCaption = function() { - if (!VEnableImageCaption) { - return; - } - - var imgs = document.getElementsByTagName('img'); - for (var i = 0; i < imgs.length; ++i) { - var img = imgs[i]; - - var type = getImageType(img); - - if (type == -1) { - continue; - } else if (type == 1) { - // Insert a div as the parent of the img. - var imgPack = document.createElement('div'); - img.insertAdjacentElement('afterend', imgPack); - imgPack.appendChild(img); - } - - // Make the parent img-package. - img.parentNode.classList.add(VImagePackageClass); - - // Make it center. - img.classList.add(VImageCenterClass); - - if (img.alt == '') { - continue; - } - - // Add caption. - var captionDiv = document.createElement('div'); - captionDiv.classList.add(VImageCaptionClass); - captionDiv.innerText = img.alt; - img.insertAdjacentElement('afterend', captionDiv); - } -} - -// The renderer specific code should call this function once thay have finished -// markdown-specifi handle logics, such as Mermaid, MathJax. -var finishLogics = function() { - content.finishLogics(); -}; - -// Escape @text to Html. -var escapeHtml = function(text) { - var map = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; - - return text.replace(/[&<>"']/g, function(m) { return map[m]; }); -}; - -// Return the topest level of @toc, starting from 1. -var baseLevelOfToc = function(p_toc) { - var level = -1; - for (i in p_toc) { - if (level == -1) { - level = p_toc[i].level; - } else if (level > p_toc[i].level) { - level = p_toc[i].level; - } - } - - if (level == -1) { - level = 1; - } - - return level; -}; - -// Handle wrong title levels, such as '#' followed by '###' -var toPerfectToc = function(p_toc, p_baseLevel) { - var i; - var curLevel = p_baseLevel - 1; - var perfToc = []; - for (i in p_toc) { - var item = p_toc[i]; - - // Insert empty header. - while (item.level > curLevel + 1) { - curLevel += 1; - var tmp = { level: curLevel, - anchor: '', - title: '[EMPTY]' - }; - perfToc.push(tmp); - } - - perfToc.push(item); - curLevel = item.level; - } - - return perfToc; -}; - -var itemToHtml = function(item) { - return '' + item.title + ''; -}; - -// Turn a perfect toc to a tree using
    -var tocToTree = function(p_toc, p_baseLevel) { - var i; - var front = '
  • '; - var ending = ['
  • ']; - var curLevel = p_baseLevel; - for (i in p_toc) { - var item = p_toc[i]; - if (item.level == curLevel) { - front += ''; - front += '
  • '; - front += itemToHtml(item); - } else if (item.level > curLevel) { - // assert(item.level - curLevel == 1) - front += '
      '; - ending.push('
    '); - front += '
  • '; - front += itemToHtml(item); - ending.push('
  • '); - curLevel = item.level; - } else { - while (item.level < curLevel) { - var ele = ending.pop(); - front += ele; - if (ele == '
') { - curLevel--; - } - } - front += ''; - front += '
  • '; - front += itemToHtml(item); - } - } - while (ending.length > 0) { - front += ending.pop(); - } - front = front.replace("
  • ", ""); - front = '
      ' + front + '
    '; - return front; -}; - -var handleToc = function(needToc) { - var baseLevel = baseLevelOfToc(toc); - var tocTree = tocToTree(toPerfectToc(toc, baseLevel), baseLevel); - content.setToc(tocTree, baseLevel); - - // Add it to html - if (needToc) { - var eles = document.getElementsByClassName('vnote-toc'); - for (var i = 0; i < eles.length; ++i) { - eles[i].innerHTML = tocTree; - } - } -}; - -// Implement mouse drag with Ctrl and left button pressed to scroll. -var vds_oriMouseClientX = 0; -var vds_oriMouseClientY = 0; -var vds_readyToScroll = false; -var vds_scrolled = false; - -window.onmousedown = function(e) { - e = e || window.event; - // Left button and Ctrl key. - if (e.buttons == 1 - && e.ctrlKey - && window.getSelection().rangeCount == 0) { - vds_oriMouseClientX = e.clientX; - vds_oriMouseClientY = e.clientY; - vds_readyToScroll = true; - vds_scrolled = false; - e.preventDefault(); - } else { - vds_readyToScroll = false; - vds_scrolled = false; - } -}; - -window.onmouseup = function(e) { - e = e || window.event; - if (vds_scrolled || vds_readyToScroll) { - // Have been scrolled, restore the cursor style. - document.body.style.cursor = "auto"; - e.preventDefault(); - } - - vds_readyToScroll = false; - vds_scrolled = false; -}; - -window.onmousemove = function(e) { - e = e || window.event; - if (vds_readyToScroll) { - deltaX = e.clientX - vds_oriMouseClientX; - deltaY = e.clientY - vds_oriMouseClientY; - - var threshold = 5; - if (Math.abs(deltaX) >= threshold || Math.abs(deltaY) >= threshold) { - vds_oriMouseClientX = e.clientX; - vds_oriMouseClientY = e.clientY; - - if (!vds_scrolled) { - vds_scrolled = true; - document.body.style.cursor = "all-scroll"; - } - - var scrollX = -deltaX; - var scrollY = -deltaY; - window.scrollBy(scrollX, scrollY); - } - - e.preventDefault(); - } -}; - -// @forward: jump forward or backward. -// @relativeLevel: 0 for the same level as current header; -// negative value for upper level; -// positive value is ignored. -var jumpTitle = function(forward, relativeLevel, repeat) { - var headers = document.querySelectorAll("h1, h2, h3, h4, h5, h6"); - if (headers.length == 0) { - return; - } - - if (currentHeaderIdx == -1) { - // At the beginning, before any headers. - if (relativeLevel < 0 || !forward) { - return; - } - } - - var targetIdx = -1; - // -1: skip level check. - var targetLevel = 0; - - var delta = 1; - if (!forward) { - delta = -1; - } - - var scrollTop = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset; - - var firstHeader = true; - for (targetIdx = (currentHeaderIdx == -1 ? 0 : currentHeaderIdx); - targetIdx >= 0 && targetIdx < headers.length; - targetIdx += delta) { - var header = headers[targetIdx]; - var level = parseInt(header.tagName.substr(1)); - if (targetLevel == 0) { - targetLevel = level; - if (relativeLevel < 0) { - targetLevel += relativeLevel; - if (targetLevel < 1) { - // Invalid level. - return false; - } - } else if (relativeLevel > 0) { - targetLevel = -1; - } - } - - if (targetLevel == -1 || level == targetLevel) { - if (targetIdx == currentHeaderIdx) { - // If current header is visible, skip it. - content.setLog("scroll " + scrollTop + " " + headers[targetIdx].offsetTop); - if (forward || scrollTop <= headers[targetIdx].offsetTop) { - continue; - } - } - - if (--repeat == 0) { - break; - } - } else if (level < targetLevel) { - return; - } - - firstHeader = false; - } - - if (targetIdx < 0 || targetIdx >= headers.length) { - return; - } - - // Disable scroll temporarily. - g_muteScroll = true; - headers[targetIdx].scrollIntoView(); - highlightAnchor(headers[targetIdx]); - currentHeaderIdx = targetIdx; - content.setHeader(headers[targetIdx].getAttribute("id")); - setTimeout("g_muteScroll = false", 100); -}; - -var renderCodeBlockLineNumber = function() { - if (!VEnableHighlightLineNumber) { - return; - } - - var codes = document.getElementsByTagName('code'); - for (var i = 0; i < codes.length; ++i) { - var code = codes[i]; - if (code.parentElement.tagName.toLowerCase() == 'pre') { - hljs.lineNumbersBlock(code); - } - } - - // Delete the last extra row. - var tables = document.getElementsByTagName('table'); - for (var i = 0; i < tables.length; ++i) { - var table = tables[i]; - if (table.classList.contains("hljs-ln")) { - var rowCount = table.rows.length; - table.deleteRow(rowCount - 1); - } - } -}; - -var addClassToCodeBlock = function() { - var hljsClass = 'hljs'; - var codes = document.getElementsByTagName('code'); - for (var i = 0; i < codes.length; ++i) { - var code = codes[i]; - if (code.parentElement.tagName.toLowerCase() == 'pre') { - code.classList.add(hljsClass); - } - } -}; - -var listContainsRegex = function(strs, exp) { - for (var i = 0, len = strs.length; i < len; ++i) { - if (exp.test(strs[i])) { - return true; - } - } - - return false; -} diff --git a/src/resources/marked.js b/src/resources/marked.js deleted file mode 100644 index 95e2251a..00000000 --- a/src/resources/marked.js +++ /dev/null @@ -1,77 +0,0 @@ -var placeholder = document.getElementById('placeholder'); -var renderer = new marked.Renderer(); -var toc = []; // Table of contents as a list -var nameCounter = 0; - -renderer.heading = function(text, level) { - // Use number to avoid issues with Chinese - var escapedText = 'toc_' + nameCounter++; - toc.push({ - level: level, - anchor: escapedText, - title: text - }); - return '' + text + ''; -}; - -// Highlight.js to highlight code block -marked.setOptions({ - highlight: function(code, lang) { - if (lang) { - if (hljs.getLanguage(lang)) { - return hljs.highlight(lang, code).value; - } else { - return hljs.highlightAuto(code).value; - } - } else { - return code; - } - } -}); - -var markdownToHtml = function(markdown, needToc) { - toc = []; - nameCounter = 0; - var html = marked(markdown, { renderer: renderer }); - if (needToc) { - return html.replace(/

    \[TOC\]<\/p>/ig, '

    '); - } else { - return html; - } -}; - -var mdHasTocSection = function(markdown) { - var n = markdown.search(/(\n|^)\[toc\]/i); - return n != -1; -}; - -var updateText = function(text) { - var needToc = mdHasTocSection(text); - var html = markdownToHtml(text, needToc); - placeholder.innerHTML = html; - handleToc(needToc); - insertImageCaption(); - renderMermaid('lang-mermaid'); - renderFlowchart('lang-flowchart'); - addClassToCodeBlock(); - renderCodeBlockLineNumber(); - - // If you add new logics after handling MathJax, please pay attention to - // finishLoading logic. - if (VEnableMathjax) { - try { - MathJax.Hub.Queue(["Typeset", MathJax.Hub, placeholder, finishLogics]); - } catch (err) { - content.setLog("err: " + err); - finishLogics(); - } - } else { - finishLogics(); - } -}; - -var highlightText = function(text, id, timeStamp) { - var html = marked(text); - content.highlightTextCB(html, id, timeStamp); -} - diff --git a/src/resources/qwebchannel.js b/src/resources/qwebchannel.js deleted file mode 100644 index 1d84b8e7..00000000 --- a/src/resources/qwebchannel.js +++ /dev/null @@ -1,430 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebChannel module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -"use strict"; - -var QWebChannelMessageTypes = { - signal: 1, - propertyUpdate: 2, - init: 3, - idle: 4, - debug: 5, - invokeMethod: 6, - connectToSignal: 7, - disconnectFromSignal: 8, - setProperty: 9, - response: 10, -}; - -var QWebChannel = function(transport, initCallback) -{ - if (typeof transport !== "object" || typeof transport.send !== "function") { - console.error("The QWebChannel expects a transport object with a send function and onmessage callback property." + - " Given is: transport: " + typeof(transport) + ", transport.send: " + typeof(transport.send)); - return; - } - - var channel = this; - this.transport = transport; - - this.send = function(data) - { - if (typeof(data) !== "string") { - data = JSON.stringify(data); - } - channel.transport.send(data); - } - - this.transport.onmessage = function(message) - { - var data = message.data; - if (typeof data === "string") { - data = JSON.parse(data); - } - switch (data.type) { - case QWebChannelMessageTypes.signal: - channel.handleSignal(data); - break; - case QWebChannelMessageTypes.response: - channel.handleResponse(data); - break; - case QWebChannelMessageTypes.propertyUpdate: - channel.handlePropertyUpdate(data); - break; - default: - console.error("invalid message received:", message.data); - break; - } - } - - this.execCallbacks = {}; - this.execId = 0; - this.exec = function(data, callback) - { - if (!callback) { - // if no callback is given, send directly - channel.send(data); - return; - } - if (channel.execId === Number.MAX_VALUE) { - // wrap - channel.execId = Number.MIN_VALUE; - } - if (data.hasOwnProperty("id")) { - console.error("Cannot exec message with property id: " + JSON.stringify(data)); - return; - } - data.id = channel.execId++; - channel.execCallbacks[data.id] = callback; - channel.send(data); - }; - - this.objects = {}; - - this.handleSignal = function(message) - { - var object = channel.objects[message.object]; - if (object) { - object.signalEmitted(message.signal, message.args); - } else { - console.warn("Unhandled signal: " + message.object + "::" + message.signal); - } - } - - this.handleResponse = function(message) - { - if (!message.hasOwnProperty("id")) { - console.error("Invalid response message received: ", JSON.stringify(message)); - return; - } - channel.execCallbacks[message.id](message.data); - delete channel.execCallbacks[message.id]; - } - - this.handlePropertyUpdate = function(message) - { - for (var i in message.data) { - var data = message.data[i]; - var object = channel.objects[data.object]; - if (object) { - object.propertyUpdate(data.signals, data.properties); - } else { - console.warn("Unhandled property update: " + data.object + "::" + data.signal); - } - } - channel.exec({type: QWebChannelMessageTypes.idle}); - } - - this.debug = function(message) - { - channel.send({type: QWebChannelMessageTypes.debug, data: message}); - }; - - channel.exec({type: QWebChannelMessageTypes.init}, function(data) { - for (var objectName in data) { - var object = new QObject(objectName, data[objectName], channel); - } - // now unwrap properties, which might reference other registered objects - for (var objectName in channel.objects) { - channel.objects[objectName].unwrapProperties(); - } - if (initCallback) { - initCallback(channel); - } - channel.exec({type: QWebChannelMessageTypes.idle}); - }); -}; - -function QObject(name, data, webChannel) -{ - this.__id__ = name; - webChannel.objects[name] = this; - - // List of callbacks that get invoked upon signal emission - this.__objectSignals__ = {}; - - // Cache of all properties, updated when a notify signal is emitted - this.__propertyCache__ = {}; - - var object = this; - - // ---------------------------------------------------------------------- - - this.unwrapQObject = function(response) - { - if (response instanceof Array) { - // support list of objects - var ret = new Array(response.length); - for (var i = 0; i < response.length; ++i) { - ret[i] = object.unwrapQObject(response[i]); - } - return ret; - } - if (!response - || !response["__QObject*__"] - || response.id === undefined) { - return response; - } - - var objectId = response.id; - if (webChannel.objects[objectId]) - return webChannel.objects[objectId]; - - if (!response.data) { - console.error("Cannot unwrap unknown QObject " + objectId + " without data."); - return; - } - - var qObject = new QObject( objectId, response.data, webChannel ); - qObject.destroyed.connect(function() { - if (webChannel.objects[objectId] === qObject) { - delete webChannel.objects[objectId]; - // reset the now deleted QObject to an empty {} object - // just assigning {} though would not have the desired effect, but the - // below also ensures all external references will see the empty map - // NOTE: this detour is necessary to workaround QTBUG-40021 - var propertyNames = []; - for (var propertyName in qObject) { - propertyNames.push(propertyName); - } - for (var idx in propertyNames) { - delete qObject[propertyNames[idx]]; - } - } - }); - // here we are already initialized, and thus must directly unwrap the properties - qObject.unwrapProperties(); - return qObject; - } - - this.unwrapProperties = function() - { - for (var propertyIdx in object.__propertyCache__) { - object.__propertyCache__[propertyIdx] = object.unwrapQObject(object.__propertyCache__[propertyIdx]); - } - } - - function addSignal(signalData, isPropertyNotifySignal) - { - var signalName = signalData[0]; - var signalIndex = signalData[1]; - object[signalName] = { - connect: function(callback) { - if (typeof(callback) !== "function") { - console.error("Bad callback given to connect to signal " + signalName); - return; - } - - object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || []; - object.__objectSignals__[signalIndex].push(callback); - - if (!isPropertyNotifySignal && signalName !== "destroyed") { - // only required for "pure" signals, handled separately for properties in propertyUpdate - // also note that we always get notified about the destroyed signal - webChannel.exec({ - type: QWebChannelMessageTypes.connectToSignal, - object: object.__id__, - signal: signalIndex - }); - } - }, - disconnect: function(callback) { - if (typeof(callback) !== "function") { - console.error("Bad callback given to disconnect from signal " + signalName); - return; - } - object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || []; - var idx = object.__objectSignals__[signalIndex].indexOf(callback); - if (idx === -1) { - console.error("Cannot find connection of signal " + signalName + " to " + callback.name); - return; - } - object.__objectSignals__[signalIndex].splice(idx, 1); - if (!isPropertyNotifySignal && object.__objectSignals__[signalIndex].length === 0) { - // only required for "pure" signals, handled separately for properties in propertyUpdate - webChannel.exec({ - type: QWebChannelMessageTypes.disconnectFromSignal, - object: object.__id__, - signal: signalIndex - }); - } - } - }; - } - - /** - * Invokes all callbacks for the given signalname. Also works for property notify callbacks. - */ - function invokeSignalCallbacks(signalName, signalArgs) - { - var connections = object.__objectSignals__[signalName]; - if (connections) { - connections.forEach(function(callback) { - callback.apply(callback, signalArgs); - }); - } - } - - this.propertyUpdate = function(signals, propertyMap) - { - // update property cache - for (var propertyIndex in propertyMap) { - var propertyValue = propertyMap[propertyIndex]; - object.__propertyCache__[propertyIndex] = propertyValue; - } - - for (var signalName in signals) { - // Invoke all callbacks, as signalEmitted() does not. This ensures the - // property cache is updated before the callbacks are invoked. - invokeSignalCallbacks(signalName, signals[signalName]); - } - } - - this.signalEmitted = function(signalName, signalArgs) - { - invokeSignalCallbacks(signalName, signalArgs); - } - - function addMethod(methodData) - { - var methodName = methodData[0]; - var methodIdx = methodData[1]; - object[methodName] = function() { - var args = []; - var callback; - for (var i = 0; i < arguments.length; ++i) { - if (typeof arguments[i] === "function") - callback = arguments[i]; - else - args.push(arguments[i]); - } - - webChannel.exec({ - "type": QWebChannelMessageTypes.invokeMethod, - "object": object.__id__, - "method": methodIdx, - "args": args - }, function(response) { - if (response !== undefined) { - var result = object.unwrapQObject(response); - if (callback) { - (callback)(result); - } - } - }); - }; - } - - function bindGetterSetter(propertyInfo) - { - var propertyIndex = propertyInfo[0]; - var propertyName = propertyInfo[1]; - var notifySignalData = propertyInfo[2]; - // initialize property cache with current value - // NOTE: if this is an object, it is not directly unwrapped as it might - // reference other QObject that we do not know yet - object.__propertyCache__[propertyIndex] = propertyInfo[3]; - - if (notifySignalData) { - if (notifySignalData[0] === 1) { - // signal name is optimized away, reconstruct the actual name - notifySignalData[0] = propertyName + "Changed"; - } - addSignal(notifySignalData, true); - } - - Object.defineProperty(object, propertyName, { - configurable: true, - get: function () { - var propertyValue = object.__propertyCache__[propertyIndex]; - if (propertyValue === undefined) { - // This shouldn't happen - console.warn("Undefined value in property cache for property \"" + propertyName + "\" in object " + object.__id__); - } - - return propertyValue; - }, - set: function(value) { - if (value === undefined) { - console.warn("Property setter for " + propertyName + " called with undefined value!"); - return; - } - object.__propertyCache__[propertyIndex] = value; - webChannel.exec({ - "type": QWebChannelMessageTypes.setProperty, - "object": object.__id__, - "property": propertyIndex, - "value": value - }); - } - }); - - } - - // ---------------------------------------------------------------------- - - data.methods.forEach(addMethod); - - data.properties.forEach(bindGetterSetter); - - data.signals.forEach(function(signal) { addSignal(signal, false); }); - - for (var name in data.enums) { - object[name] = data.enums[name]; - } -} - -//required for use with nodejs -if (typeof module === 'object') { - module.exports = { - QWebChannel: QWebChannel - }; -} diff --git a/src/resources/showdown.js b/src/resources/showdown.js deleted file mode 100644 index 8743b305..00000000 --- a/src/resources/showdown.js +++ /dev/null @@ -1,111 +0,0 @@ -var placeholder = document.getElementById('placeholder'); -var renderer = new showdown.Converter({simplifiedAutoLink: 'true', - excludeTrailingPunctuationFromURLs: 'true', - strikethrough: 'true', - tables: 'true', - tasklists: 'true', - literalMidWordUnderscores: 'true', - extensions: ['headinganchor'] - }); - -var toc = []; // Table of contents as a list - -// Parse the html's headings and construct toc[]. -var parseHeadings = function(html) { - toc = []; - var parser = new DOMParser(); - var htmlDoc = parser.parseFromString(html, 'text/html'); - var eles = htmlDoc.querySelectorAll("h1, h2, h3, h4, h5, h6"); - - for (var i = 0; i < eles.length; ++i) { - var ele = eles[i]; - var level = parseInt(ele.tagName.substr(1)); - - toc.push({ - level: level, - anchor: ele.id, - title: ele.innerHTML - }); - } - - delete parser; -}; - -var markdownToHtml = function(markdown, needToc) { - var html = renderer.makeHtml(markdown); - - // Parse the html to init toc[]. - parseHeadings(html); - - if (needToc) { - return html.replace(/

    \[TOC\]<\/p>/ig, '

    '); - } else { - return html; - } -}; - -var mdHasTocSection = function(markdown) { - var n = markdown.search(/(\n|^)\[toc\]/i); - return n != -1; -}; - -var highlightCodeBlocks = function(doc, enableMermaid, enableFlowchart) { - var codes = doc.getElementsByTagName('code'); - for (var i = 0; i < codes.length; ++i) { - var code = codes[i]; - if (code.parentElement.tagName.toLowerCase() == 'pre') { - if (enableMermaid && code.classList.contains('language-mermaid')) { - // Mermaid code block. - continue; - } if (enableFlowchart && code.classList.contains('language-flowchart')) { - // Flowchart code block. - continue; - } - - if (listContainsRegex(code.classList, /language-.*/)) { - hljs.highlightBlock(code); - } - } - } -}; - -var updateText = function(text) { - var needToc = mdHasTocSection(text); - var html = markdownToHtml(text, needToc); - placeholder.innerHTML = html; - handleToc(needToc); - insertImageCaption(); - highlightCodeBlocks(document, VEnableMermaid, VEnableFlowchart); - renderMermaid('language-mermaid'); - renderFlowchart('language-flowchart'); - addClassToCodeBlock(); - renderCodeBlockLineNumber(); - - // If you add new logics after handling MathJax, please pay attention to - // finishLoading logic. - if (VEnableMathjax) { - try { - MathJax.Hub.Queue(["Typeset", MathJax.Hub, placeholder, finishLogics]); - } catch (err) { - content.setLog("err: " + err); - finishLogics(); - } - } else { - finishLogics(); - } -}; - -var highlightText = function(text, id, timeStamp) { - var html = renderer.makeHtml(text); - - var parser = new DOMParser(); - var htmlDoc = parser.parseFromString("
    " + html + "
    ", 'text/html'); - highlightCodeBlocks(htmlDoc, false, false); - - html = htmlDoc.getElementById('showdown-container').innerHTML; - - delete parser; - - content.highlightTextCB(html, id, timeStamp); -} - diff --git a/src/resources/themes/v_material/arrow_dropdown.svg b/src/resources/themes/v_material/arrow_dropdown.svg deleted file mode 100644 index dcfad993..00000000 --- a/src/resources/themes/v_material/arrow_dropdown.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/src/resources/themes/v_material/branch_closed.svg b/src/resources/themes/v_material/branch_closed.svg deleted file mode 100644 index 18c6857d..00000000 --- a/src/resources/themes/v_material/branch_closed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_material/branch_end.svg b/src/resources/themes/v_material/branch_end.svg deleted file mode 100644 index baa0c23f..00000000 --- a/src/resources/themes/v_material/branch_end.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 2 - - - - diff --git a/src/resources/themes/v_material/branch_more.svg b/src/resources/themes/v_material/branch_more.svg deleted file mode 100644 index cb0fecad..00000000 --- a/src/resources/themes/v_material/branch_more.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 2 - - - - diff --git a/src/resources/themes/v_material/branch_open.svg b/src/resources/themes/v_material/branch_open.svg deleted file mode 100644 index c89c36ef..00000000 --- a/src/resources/themes/v_material/branch_open.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_material/checkbox_checked.svg b/src/resources/themes/v_material/checkbox_checked.svg deleted file mode 100644 index 2903aee3..00000000 --- a/src/resources/themes/v_material/checkbox_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_material/checkbox_unchecked.svg b/src/resources/themes/v_material/checkbox_unchecked.svg deleted file mode 100644 index 90565676..00000000 --- a/src/resources/themes/v_material/checkbox_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_material/close.svg b/src/resources/themes/v_material/close.svg deleted file mode 100644 index aa6b81c1..00000000 --- a/src/resources/themes/v_material/close.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_material/close_grey.svg b/src/resources/themes/v_material/close_grey.svg deleted file mode 100644 index 24bddd4e..00000000 --- a/src/resources/themes/v_material/close_grey.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_material/down.svg b/src/resources/themes/v_material/down.svg deleted file mode 100644 index 386ac7f8..00000000 --- a/src/resources/themes/v_material/down.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_material/down_disabled.svg b/src/resources/themes/v_material/down_disabled.svg deleted file mode 100644 index 2a53e0f0..00000000 --- a/src/resources/themes/v_material/down_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_material/float.svg b/src/resources/themes/v_material/float.svg deleted file mode 100644 index 3c29db9a..00000000 --- a/src/resources/themes/v_material/float.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/themes/v_material/left.svg b/src/resources/themes/v_material/left.svg deleted file mode 100644 index aee69f4a..00000000 --- a/src/resources/themes/v_material/left.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_material/left_disabled.svg b/src/resources/themes/v_material/left_disabled.svg deleted file mode 100644 index 3cabd4b5..00000000 --- a/src/resources/themes/v_material/left_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_material/line.svg b/src/resources/themes/v_material/line.svg deleted file mode 100644 index 8c981419..00000000 --- a/src/resources/themes/v_material/line.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 2 - - - diff --git a/src/resources/themes/v_material/menu_checkbox.svg b/src/resources/themes/v_material/menu_checkbox.svg deleted file mode 100644 index 0aeb35a1..00000000 --- a/src/resources/themes/v_material/menu_checkbox.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_material/menu_radiobutton.svg b/src/resources/themes/v_material/menu_radiobutton.svg deleted file mode 100644 index aafaa309..00000000 --- a/src/resources/themes/v_material/menu_radiobutton.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_material/radiobutton_checked.svg b/src/resources/themes/v_material/radiobutton_checked.svg deleted file mode 100644 index c9834cc5..00000000 --- a/src/resources/themes/v_material/radiobutton_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_material/radiobutton_unchecked.svg b/src/resources/themes/v_material/radiobutton_unchecked.svg deleted file mode 100644 index 7cd0863a..00000000 --- a/src/resources/themes/v_material/radiobutton_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_material/right.svg b/src/resources/themes/v_material/right.svg deleted file mode 100644 index c524ab79..00000000 --- a/src/resources/themes/v_material/right.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_material/right_disabled.svg b/src/resources/themes/v_material/right_disabled.svg deleted file mode 100644 index c0c83ba8..00000000 --- a/src/resources/themes/v_material/right_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_material/up.svg b/src/resources/themes/v_material/up.svg deleted file mode 100644 index 52be26da..00000000 --- a/src/resources/themes/v_material/up.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_material/up_disabled.svg b/src/resources/themes/v_material/up_disabled.svg deleted file mode 100644 index 36e54158..00000000 --- a/src/resources/themes/v_material/up_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_material/v_material.css b/src/resources/themes/v_material/v_material.css deleted file mode 100644 index c993f3b2..00000000 --- a/src/resources/themes/v_material/v_material.css +++ /dev/null @@ -1,245 +0,0 @@ -body { - margin: 0 auto; - font-family: "Microsoft YaHei", "ubuntu", "Tahoma", arial, sans-serif; - color: rgb(238, 255, 255); - background: rgb(38, 50, 56); - line-height: 1; - padding: 30px; -} - -img { - max-width: 100%; -} - -@media screen and (min-width: 1000px) { - body { - width: 842px; - margin: 10px auto; - } - -} - -h1, h2, h3, h4, h5 { - font-family: "Microsoft YaHei", "ubuntu", "Tahoma", arial, sans-serif; - font-weight: 400; - margin-top: 1em; - color: rgb(171, 232, 141); -} - -h1, h2, h3, h4, h5, dl { - margin-bottom: 16px; - padding: 0; -} - -p { - margin-top: 8px; - margin-bottom: 3px; -} - -h1 { - font-size: 32px; - line-height: 54px; -} - -h1:before { - content: '# '; -} - -h2 { - font-size: 30px; - line-height: 42px; -} - -h2:before { - content: '## '; -} - -h1, h2 { - padding-bottom: 10px; -} - -h3 { - font-size: 24px; - line-height: 30px; -} - -h3:before { - content: '### '; -} - -h4 { - font-size: 20px; - line-height: 26px; -} - -h4:before { - content: '#### '; -} - -h5 { - font-size: 18px; - line-height: 23px; -} - -h5:before { - content: '##### '; -} - -a { - color: rgb(247, 140, 108); - margin: 0 2px; - padding: 0; - vertical-align: baseline; -} - -a:hover { - - color: #0099ff; -} - -ul, ol { - padding: 0; - padding-left: 18px; - margin: 0; -} - -li { - line-height: 24px; -} - -p, ul, ol { - font-size: 16px; - line-height: 24px; -} - -ol ol, ul ol { - list-style-type: lower-roman; -} - -strong { - color: rgb(240, 113, 120); -} - -i { - color: rgb(240, 113, 120); -} - -pre { - line-height: 1.7em; - overflow: auto; - padding: 6px 10px; - /*border-left: 2px solid #6CE26C;*/ - -} - -pre code { - - font-family: Consolas, Monaco, Andale Mono, monospace; - border: 0; - background: rgb(26, 34, 38); - display: inline; - max-width: initial; - padding: 0; - margin: 0; - overflow: initial; - line-height: 1.6em; - font-size: .95em; - white-space: pre; - -} - -:not(pre) code { - border: none; - padding: 1px 3px; - color: #c792ea; - -} - -aside { - display: block; - float: right; - width: 390px; -} - -blockquote { - position: relative; - color: rgb(101, 170, 255); - font-style: italic; - font-weight: 300; - background: rgb(26, 34, 38); - border-left: 4px solid rgb(101, 115, 126); - padding-left: 1em; - -} - -blockquote cite { - font-size: 14px; - line-height: 20px; - color: #bfbfbf; -} - -blockquote cite:before { - content: '\2014 \00A0'; -} - -hr { - text-align: left; - color: #999; - height: 2px; - padding: 0; - margin: 16px 0; - background-color: #e7e7e7; - border: 0 none; -} - -dl { - padding: 0; -} - -dl dt { - padding: 10px 0; - margin-top: 16px; - font-size: 1em; - font-style: italic; - font-weight: bold; -} - -dl dd { - padding: 0 16px; - margin-bottom: 16px; -} - -dd { - margin-left: 0; -} - -table { - *border-collapse: collapse; /* IE7 and lower */ - border-spacing: 0; - width: 100%; - border: 1px solid #eeffff; - margin: 0px; - padding: 5px 10px; - font-weight: bold; -} - -pre table { - border: 0; -} - -::-webkit-scrollbar-track { - /*-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);*/ - background-color: #263238; - border-radius: 10px; -} - -::-webkit-scrollbar { - width: 10px; - background-color: #263238; -} - -::-webkit-scrollbar-thumb { - background-color: #1a2226; - border-radius: 10px; -} - diff --git a/src/resources/themes/v_material/v_material.mdhl b/src/resources/themes/v_material/v_material.mdhl deleted file mode 100644 index 990b97d9..00000000 --- a/src/resources/themes/v_material/v_material.mdhl +++ /dev/null @@ -1,172 +0,0 @@ -# This is the default markdown styles used for Peg-Markdown-Highlight -# created by Le Tan(tamlokveer@gmail.com). -# For a complete description of the syntax, please refer to the original -# documentation of the style parser -# [The Syntax of PEG Markdown Highlight Stylesheets](http://hasseg.org/peg-markdown-highlight/docs/stylesheet_syntax.html). -# VNote adds some styles in the syntax which will be marked [VNote] in the comment. -# -# Note: Empty lines within a section is NOT allowed. -# Note: Do NOT modify this file directly. Copy it and tune your own style! - -editor -foreground: eeffff -background: 263238 -caret: FFCC00 -# QTextEdit just choose the first available font, so specify the Chinese fonts first -# Do not use "" to quote the name -font-family: Hiragino Sans GB, 冬青黑体, Microsoft YaHei, 微软雅黑, Microsoft YaHei UI, WenQuanYi Micro Hei, 文泉驿雅黑, Dengxian, 等线体, STXihei, 华文细黑, Liberation Sans, Droid Sans, NSimSun, 新宋体, SimSun, 宋体, Helvetica, sans-serif, Tahoma, Arial, Verdana, Geneva, Georgia, Times New Roman -font-size: 18 -# [VNote] Style for trailing space -trailing-space: a8a8a8 -# [VNote] Style for line number -line-number-background: 263238 -line-number-foreground: 374650 -# [VNote] style for selected word highlight -selected-word-background: dfdf00 -# [VNote] style for searched word highlight -searched-word-background: 4db6ac -# [VNote] style for searched word under cursor highlight -searched-word-cursor-background: 66bb6a -# [VNote] style for incremental searched word highlight -incremental-searched-word-background: ce93d8 - - - -editor-selection -foreground: eeeeee -background: 444444 - -editor-current-line -background: 1a2227 -# [VNote] Vim insert mode cursor line background -vim-insert-background: bcbcbc -# [VNote] Vim normal mode cursor line background -vim-normal-background: b0bec5 -# [VNote] Vim visual mode cursor line background -vim-visual-background: 90caf9 -# [VNote] Vim replace mode cursor line background -vim-replace-background: f8bbd0 - -H1 -foreground: ABE88D -font-style: bold -font-size: +8 - -H2 -foreground: ABE88D -font-style: bold -font-size: +6 - -H3 -foreground: ABE88D -font-style: bold -font-size: +4 - -H4 -foreground: ABE88D -font-style: bold -font-size: +2 - -H5 -foreground: ABE88D -font-style: bold -font-size: +2 - -H6 -foreground: ABE88D -font-style: bold -font-size: +2 - -HRULE -foreground: 586e75 - -LIST_BULLET -foreground: d33682 -font-style: bold -font-size: +2 - -LIST_ENUMERATOR -foreground: 0000ff - -LINK -foreground: F78C6C -font-style: underlined - -AUTO_LINK_URL -foreground: F78C6C -font-style: underlined - -AUTO_LINK_EMAIL -foreground: 005fff -font-style: underlined - -IMAGE -foreground: 616161 - -REFERENCE -foreground: b58900 - -CODE -foreground: C792EA -font-family: Consolas, Monaco, Andale Mono, Monospace, Courier New - -EMPH -font-style: italic - - -STRONG -font-style: bold -foreground: f78c6c - -HTML_ENTITY -foreground: 6c71c4 - -COMMENT -foreground: 93a1a1 - -VERBATIM -foreground: c792ea -font-family: Consolas, Monaco, Andale Mono, Monospace, Courier New -# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, color) -# The last occurence of the same attribute takes effect -hljs-comment: 546e7a -hljs-keyword: c792ea -hljs-attribute: c3e88d -hljs-selector-tag: c792ea -hljs-meta-keyword: c3e88d -hljs-doctag: c3e88d -hljs-name: c3e88d -hljs-type: ffcb6b -hljs-string: c3e176 -hljs-number: f78c6c -hljs-selector-id: 880000 -hljs-selector-class: 880000 -hljs-quote: 546e7a -hljs-template-tag: 880000 -hljs-deletion: 880000 -# Could specify multiple attribute in one line -hljs-title: bold, ffcb6b -hljs-section: bold, 880000 -hljs-regexp: bc6060 -hljs-symbol: bc6060 -hljs-variable: bc6060 -hljs-template-variable: bc6060 -hljs-link: bc6060 -hljs-selector-attr: bc6060 -hljs-selector-pseudo: bc6060 -hljs-literal: af00d7 -hljs-built_in: 008700 -hljs-bullet: 008700 -hljs-code: 008700 -hljs-addition: 008700 -hljs-meta: 1f7199 -hljs-meta-string: 4d99bf -hljs-emphasis: italic -hljs-strong: bold - -BLOCKQUOTE -foreground: 65aaff -font-style: italic - -STRIKE -strike-color: 586e75 diff --git a/src/resources/themes/v_material/v_material.palette b/src/resources/themes/v_material/v_material.palette deleted file mode 100644 index 75ff09a1..00000000 --- a/src/resources/themes/v_material/v_material.palette +++ /dev/null @@ -1,309 +0,0 @@ -; File path could be absolute path or relative path (related to this file). -; Use @color_tag to reference a style. - -[metadata] -qss_file=v_material.qss -mdhl_file=v_material.mdhl -css_file=v_material.css -codeblock_css_file=v_material_codeblock.css - -[phony] -; Abstract color attributes. - - -master_fg=#eeffff - -master_bg=#80cbc4 - -base_fg=#80cbc4 - -base_bg=#263238 - - -main_fg=@base_fg -main_bg=#base_bg - -title_fg=@base_fg -title_bg=@base_bg - -disabled_fg=#9E9E9E - -content_fg=@base_fg -content_bg=@base_bg - -border_bg=#212b30 - -separator_bg=#D3D3D3 - -hover_fg=@base_fg -hover_bg=#1a2227 - -selected_fg=@base_fg -selected_bg=#1a2227 - -active_fg=@selected_fg -active_bg=@selected_bg - -inactive_fg=@selected_fg -inactive_bg=#1a2227 - -focus_fg=@selected_fg -focus_bg=@selected_bg - -pressed_fg=@base_fg - -pressed_bg=#b2b2b2 - -edit_fg=#eeffff - -edit_bg=@base_bg -edit_focus_bg=#1a2227 -edit_focus_border=@master_bg -edit_selection_fg=@edit_fg -edit_selection_bg=#31454a - -danger_red=#C9302C -icon_fg=#eeffff - -[soft_defined] -; VAvatar. -avatar_border_bg=@selected_bg -avatar_fg=@base_bg -avatar_bg=@base_fg -; The border background color of the avatar when Captain mode is triggered. -avatar_captain_mode_border_bg=@master_bg - -; Style of the label in Navigation mode. -navigation_label_fg=@master_fg -navigation_label_bg=@master_bg - -; Style of the bubble of VButtonWithWidget. -bubble_fg=@80cbc4 -bubble_bg=@master_bg - -; Icons' foreground. -danger_icon_fg=@danger_red -item_icon_fg=@icon_fg -title_icon_fg=@icon_fg - -; VVimIndicator. -vim_indicator_key_label_fg=@base_fg -vim_indicator_mode_label_fg=@base_fg -vim_indicator_cmd_edit_pending_bg=@selected_bg - -; VTabIndicator. -tab_indicator_label_fg=@base_fg - -[widgets] -; Widget color attributes. - -; QWidget. -widget_fg=@base_fg - -; Separator of dock widgets. -dock_separator_bg=@border_bg -dock_separator_hover_bg=@border_bg - -; Menubar. -menubar_bg=@main_bg -menubar_fg=@main_fg -menubar_item_selected_bg=@selected_bg - -; Menu. -menu_bg=@base_bg -menu_fg=@base_fg -menu_item_disabled_fg=@disabled_fg -menu_item_selected_fg=@selected_fg -menu_item_selected_bg=@selected_bg -menu_separator_bg=@separator_bg -menu_icon_fg=@icon_fg -menu_icon_danger_fg=@danger_icon_fg - -; Tooltip. -tooltip_bg=@master_bg -tooltip_fg=@master_fg - -; Toolbar. -toolbar_bg=@main_bg -toolbutton_hover_bg=@hover_bg -toolbutton_pressed_bg=@pressed_bg -toolbutton_checked_bg=@selected_bg -toolbutton_icon_fg=@icon_fg -toolbutton_icon_danger_fg=@danger_icon_fg - -; Toolbox. -toolbox_icon_fg=@icon_fg - -; Dockwidget. -dockwidget_title_fg=@title_fg -dockwidget_title_bg=@title_bg -dockwidget_button_hover_bg=@hover_bg - -; PushButton. -pushbutton_fg=@base_fg -pushbutton_bg=transparent -pushbutton_border=@border_bg -pushbutton_pressed_bg=@pressed_bg -pushbutton_checked_bg=@selected_bg -pushbutton_hover_bg=@hover_bg -pushbutton_default_border=@master_bg - -pushbutton_specialbtn_fg=@master_fg -pushbutton_specialbtn_bg=@master_bg -pushbutton_specialbtn_hover_bg=#3F51B5 -pushbutton_specialbtn_checked_bg=#3949AB -pushbutton_specialbtn_pressed_bg=#303F9F - -pushbutton_cornerbtn_hover_bg=@hover_bg -pushbutton_cornerbtn_focus_bg=@focus_bg -pushbutton_cornerbtn_pressed_bg=@pressed_bg - -pushbutton_statusbtn_hover_bg=@hover_bg -pushbutton_statusbtn_focus_bg=@focus_bg -pushbutton_statusbtn_pressed_bg=@pressed_bg - -pushbutton_flatbtn_hover_bg=@hover_bg -pushbutton_flatbtn_focus_bg=@focus_bg -pushbutton_flatbtn_pressed_bg=@pressed_bg - -pushbutton_selectionbtn_hover_bg=@hover_bg -pushbutton_selectionbtn_focus_bg=@focus_bg -pushbutton_selectionbtn_pressed_bg=@pressed_bg - -pushbutton_titlebtn_bg=@title_bg -pushbutton_titlebtn_hover_bg=@hover_bg -pushbutton_titlebtn_focus_bg=@focus_bg -pushbutton_titlebtn_pressed_bg=@pressed_bg - -pushbutton_dangerbtn_fg=#FFF -pushbutton_dangerbtn_border=#D43F3A -pushbutton_dangerbtn_bg=#D9534F -pushbutton_dangerbtn_hover_fg=#FFF -pushbutton_dangerbtn_hover_bg=#C9302C -pushbutton_dangerbtn_hover_border=#AC2925 - -button_icon_fg=@icon_fg -button_icon_danger_fg=@danger_icon_fg - -; ComboBox. -combobox_border=@border_bg -combobox_fg=@content_fg -combobox_bg=@content_bg -combobox_view_border=@border_bg -combobox_view_selected_bg=@selected_bg -combobox_view_selected_fg=@selected_fg -combobox_view_item_hover_fg=@hover_fg -combobox_view_item_hover_bg=@hover_bg -combobox_focus_bg=@edit_focus_bg -combobox_focus_border=@edit_focus_border -combobox_item_icon_fg=@item_icon_fg - -; Label. -label_fg=@base_fg -label_titlelabel_fg=@title_fg -label_titlelabel_bg=@title_bg - -; LineEdit. -lineedit_border=@border_bg -lineedit_fg=@edit_fg -lineedit_bg=@edit_bg -lineedit_focus_bg=@edit_focus_bg -lineedit_focus_border=@edit_focus_border -lineedit_selection_fg=@edit_selection_fg -lineedit_selection_bg=@edit_selection_bg - -; TabWidget. -tabwidget_pane_border=@selected_bg - -; TabBar. -tabbar_fg=@base_fg -tabbar_bg=@base_bg -tabbar_border=@border_bg - -tabbar_selected_fg=@edit_fg -tabbar_selected_bg=@edit_bg -tabbar_selected_border=@border_bg - -tabbar_hover_fg=@hover_fg -tabbar_hover_bg=@hover_bg - -tabbar_icon_fg=@icon_fg -tabbar_icon_special_fg=@danger_red - -; SelectorItem. -selectoritem_border=@base_fg -selectoritem_fg=@base_fg -selectoritem_bg=@base_bg - -; InsertSelector. -insertselector_bg=@base_bg - -; TreeView. -treeview_fg=@content_fg -treeview_bg=@content_bg -treeview_item_hover_fg=@hover_fg -treeview_item_hover_bg=@hover_bg -treeview_item_selected_fg=@selected_fg -treeview_item_selected_bg=@selected_bg -treeview_item_selected_avtive_fg=@active_fg -treeview_item_selected_avtive_bg=@active_bg -treeview_item_selected_inactive_fg=@inactive_fg -treeview_item_selected_inactive_bg=@inactive_bg -treeview_item_icon_fg=@item_icon_fg - -; ListView. -listview_fg=@content_fg -listview_bg=@content_bg -listview_item_hover_fg=@hover_fg -listview_item_hover_bg=@hover_bg -listview_item_selected_fg=@selected_fg -listview_item_selected_bg=@selected_bg -listview_item_selected_avtive_fg=@active_fg -listview_item_selected_avtive_bg=@active_bg -listview_item_selected_inactive_fg=@inactive_fg -listview_item_selected_inactive_bg=@inactive_bg - -; Splitter. -splitter_handle_bg=@border_bg - -; StatusBar. -statusbar_fg=@main_fg -statusbar_bg=@main_bg - - -; ScrollBar. -scrollbar_bg=@base_bg -scrollbar_page_bg=transparent -scrollbar_handle_bg=#222c31 -scrollbar_handle_hover_bg=@hover_bg -scrollbar_handle_pressed_bg=@pressed_bg - -; VEditWindow. -editwindow_corner_icon_fg=@master_bg -editwindow_corner_icon_inactive_fg=#D3D3D3 - -; CheckBox. -checkbox_indicator_hover_bg=@hover_bg -checkbox_indicator_pressed_bg=@pressed_bg - -; RadioButton. -radiobutton_indicator_hover_bg=@hover_bg -radiobutton_indicator_pressed_bg=@pressed_bg - -; SpinBox. -spinbox_fg=@edit_fg -spinbox_bg=@edit_bg -spinbox_border=@border_bg -spinbox_selection_fg=@edit_selection_fg -spinbox_selection_bg=@edit_selection_bg -spinbox_focus_border=@edit_focus_border -spinbox_focus_bg=@edit_focus_bg -spinbox_button_hover_bg=@hover_bg -spinbox_button_pressed_bg=@pressed_bg - -; HeaderView. -headerview_bg=#E0E0E0 -headerview_fg=@base_fg -headerview_border=@border_bg -headerview_checked_fg=@selected_fg -headerview_checked_bg=@selected_bg diff --git a/src/resources/themes/v_material/v_material.qss b/src/resources/themes/v_material/v_material.qss deleted file mode 100644 index 64efa0a4..00000000 --- a/src/resources/themes/v_material/v_material.qss +++ /dev/null @@ -1,1127 +0,0 @@ -QToolTip -{ - border: none; - background: @tooltip_bg; - color: @tooltip_fg; -} - -/* QWidget */ -QWidget -{ - color: @widget_fg; -} - -QWidget[NotebookPanel="true"] { - padding-left: 3px; -} - -/* End QWidget */ - -/* QMainWindow */ -QMainWindow { - color: @base_fg; - background: @base_bg; -} - -QMainWindow::separator { - background: @dock_separator_bg; - width: 2px; - height: 2px; -} - -QMainWindow::separator:hover { - background: @dock_separator_hover_bg; -} -/* End QMainWindow */ - -QMenuBar { - border: none; - background: @menubar_bg; - color: @menubar_fg; -} - -QMenuBar::item:selected { - background: @menubar_item_selected_bg; -} - -/* QMenu */ -QMenu { - background: @menu_bg; - color: @menu_fg; - margin: 2px; -} - -QMenu::icon { - margin: 5px; -} - -QMenu::item { - padding: 5px 30px 5px 30px; - border: 1px solid transparent; -} - -QMenu::item:disabled { - color: @menu_item_disabled_fg; -} - -QMenu::item:selected { - color: @menu_item_selected_fg; - background: @menu_item_selected_bg; -} - -QMenu::icon:checked { /* appearance of a 'checked' icon */ - border: 2px solid @menu_fg; -} - -QMenu::separator { - height: 2px; - background: @menu_separator_bg; - margin-left: 10px; - margin-right: 5px; -} - -QMenu::indicator { - width: 20px; - height: 20px; -} - -QMenu::indicator:non-exclusive:unchecked { - image: none; -} - -QMenu::indicator:non-exclusive:checked { - image: url(menu_checkbox.svg); -} - -QMenu::indicator:exclusive:unchecked { - image: none; -} - -QMenu::indicator:exclusive:checked { - image: url(menu_radiobutton.svg); -} -/* End QMenu */ - -QToolBar { - border: none; - background: @toolbar_bg; -} - -/* QToolButton */ -QToolButton { - border: none; - background: transparent; - margin: 1px 3px 1px 3px; - padding: 0px; -} - -QToolButton[popupMode="1"] { /* only for MenuButtonPopup */ - padding-right: 16px; /* make way for the popup button */ -} - -QToolButton[popupMode="2"] { /* only for InstantPopup */ - padding-right: 10px; /* make way for the popup button */ -} - -QToolButton:hover { - border:none; - background: @toolbutton_hover_bg; -} - -QToolButton:pressed { - background: @toolbutton_pressed_bg; -} - -QToolButton:checked { - background: @toolbutton_checked_bg; -} - -QToolButton:checked:hover { - background: @toolbutton_hover_bg; -} - -/* the subcontrols below are used only in the MenuButtonPopup mode */ -QToolButton::menu-button { - border: none; - width: 16px; -} - -QToolButton::menu-arrow { - image: url(arrow_dropdown.svg); - width: 16px; - height: 16px; -} -/* End QToolButton*/ - -/* DockWidget */ -QDockWidget { - color: @dockwidget_title_fg; - titlebar-close-icon: url(close.svg); - titlebar-normal-icon: url(float.svg); -} - -QDockWidget::Title { - background: @dockwidget_title_bg; - text-align: center left; -} - -QDockWidget::close-button, QDockWidget::float-button { - border: none; -} - -QDockWidget::close-button:hover, QDockWidget::float-button:hover { - background: @dockwidget_button_hover_bg; -} -/* End DockWidget */ - -/* QPushButton */ -QPushButton { - color: @pushbutton_fg; - background: @pushbutton_bg; - border: 1px solid @pushbutton_border; - padding: 3px; - min-width: 80px; -} - -QPushButton:pressed { - background-color: @pushbutton_pressed_bg; -} - -QPushButton:checked { - background-color: @pushbutton_checked_bg; -} - -QPushButton:checked:hover { - background-color: @pushbutton_hover_bg; -} - -QPushButton:hover { - background-color: @pushbutton_hover_bg; -} - -QPushButton:flat { - border: none; -} - -QPushButton:default { - border-color: @pushbutton_default_border; -} - -QPushButton::menu-indicator { - image: url(arrow_dropdown.svg); - width: 16px; - height: 16px; -} - -QPushButton[SpecialBtn="true"] { - color: @pushbutton_specialbtn_fg; - background: @pushbutton_specialbtn_bg; -} - -QPushButton[SpecialBtn="true"]:pressed { - background-color: @pushbutton_specialbtn_pressed_bg; -} - -QPushButton[SpecialBtn="true"]:checked { - background-color: @pushbutton_specialbtn_checked_bg; -} - -QPushButton[SpecialBtn="true"]:checked:hover { - background-color: @pushbutton_specialbtn_hover_bg; -} - -QPushButton[SpecialBtn="true"]:hover { - background-color: @pushbutton_specialbtn_hover_bg; -} - -QPushButton[CornerBtn="true"] { - padding: 4px -2px 4px -2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[CornerBtn="true"]::menu-indicator { - image: none; -} - -QPushButton[CornerBtn="true"]:hover { - background-color: @pushbutton_cornerbtn_hover_bg; -} - -QPushButton[CornerBtn="true"]:focus { - background-color: @pushbutton_cornerbtn_focus_bg; -} - -QPushButton[CornerBtn="true"]:pressed { - background-color: @pushbutton_cornerbtn_pressed_bg; -} - -QPushButton[StatusBtn="true"] { - font: bold; - padding: 0px 2px 0px 2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[StatusBtn="true"]:hover { - background-color: @pushbutton_statusbtn_hover_bg; -} - -QPushButton[StatusBtn="true"]:focus { - background-color: @pushbutton_statusbtn_focus_bg;; -} - -QPushButton[StatusBtn="true"]:pressed { - background-color: @pushbutton_statusbtn_pressed_bg; -} - -QPushButton[FlatBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[FlatBtn="true"]:hover { - background-color: @pushbutton_flatbtn_hover_bg; -} - -QPushButton[FlatBtn="true"]:focus { - background-color: @pushbutton_flatbtn_focus_bg; -} - -QPushButton[FlatBtn="true"]:focus { - background-color: @pushbutton_flatbtn_pressed_bg; -} - -QPushButton[SelectionBtn="true"] { - padding: 4px 10px 4px 10px; - border: none; - background-color: transparent; - font-size: 15pt; - text-align: left; - min-width: -1; -} - -QPushButton[SelectionBtn="true"]:hover { - background-color: @pushbutton_selectionbtn_hover_bg; -} - -QPushButton[SelectionBtn="true"]:focus { - background-color: @pushbutton_selectionbtn_focus_bg; -} - -QPushButton[SelectionBtn="true"]:focus { - background-color: @pushbutton_selectionbtn_pressed_bg; -} - -QPushButton[TitleBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: @pushbutton_titlebtn_bg; - min-width: -1; -} - -QPushButton[TitleBtn="true"]:hover { - background-color: @pushbutton_titlebtn_hover_bg; -} - -QPushButton[TitleBtn="true"]:focus { - background-color: @pushbutton_titlebtn_focus_bg; -} - -QPushButton[TitleBtn="true"]:focus { - background-color: @pushbutton_titlebtn_pressed_bg; -} - -QPushButton[DangerBtn="true"] { - color: @pushbutton_dangerbtn_fg; - border-color: @pushbutton_dangerbtn_border; - background-color: @pushbutton_dangerbtn_bg; - min-width: -1; -} - -QPushButton[DangerBtn="true"]:hover { - color: @pushbutton_dangerbtn_hover_fg; - border-color: @pushbutton_dangerbtn_hover_border; - background-color: @pushbutton_dangerbtn_hover_bg; -} - -VButtonMenuItem { - padding: 5px; - padding-right: 30px; - border: 1px solid transparent; - background-color: transparent; - min-width: -1; - text-align: left; -} - -VButtonMenuItem[Heading1="true"] { - font-size: 22pt; -} - -VButtonMenuItem[Heading2="true"] { - font-size: 20pt; -} - -VButtonMenuItem[Heading3="true"] { - font-size: 18pt; -} - -VButtonMenuItem[Heading4="true"] { - font-size: 16pt; -} - -VButtonMenuItem[Heading5="true"] { - font-size: 14pt; -} - -VButtonMenuItem[Heading6="true"] { - font-size: 14pt; -} - -VButtonMenuItem:hover { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:focus { - background-color: @menubar_item_selected_bg; -} -/* End QPushButton*/ - -/* QComboBox */ -QComboBox { - padding: 3px; - color: @combobox_fg; - background: @combobox_bg; - border: 1px solid @combobox_border; -} - -QComboBox:focus, QComboBox:on { - background-color: @combobox_focus_bg; - border: 2px solid @combobox_focus_border; -} - -QComboBox::drop-down { - subcontrol-origin: padding; - subcontrol-position: top right; - width: 20px; - border: none; - background: transparent; -} - -QComboBox::down-arrow { - image: url(arrow_dropdown.svg); - width: 20px; - height: 20px; -} - -QComboBox QAbstractItemView { - padding: 2px; - border: 1px solid @combobox_view_border; - background: @combobox_bg; - selection-color: @combobox_view_selected_fg; - selection-background-color: @combobox_view_selected_bg; -} - -QComboBox QAbstractItemView::item { - background: transparent; - padding: 3px; -} - -QComboBox QAbstractItemView::item:hover { - color: @combobox_view_item_hover_fg; - background: @combobox_view_item_hover_bg; -} - -QComboBox#NotebookSelector { - border: none; - font-size: 13pt; - padding-top: 3px; - padding-bottom: 3px; - icon-size: 30px; -} - -QComboBox#NotebookSelector:focus, QComboBox#NotebookSelector:on { - border: none; - background: @combobox_bg -} - -QComboBox#NotebookSelector QListWidget { - border: 1px solid @combobox_view_border; - background-color: @combobox_bg; - font-size: 13pt; - icon-size: 30px; -} - -QComboBox#NotebookSelector QListWidget::item { - padding-top: 10px; - padding-bottom: 10px; -} - -QComboBox#NotebookSelector QListWidget::item:hover { - color: @combobox_view_item_hover_fg; - background-color: @combobox_view_item_hover_bg; -} -/* End QComboBox */ - -/* QLabel */ -QLabel { - border: none; - color: @label_fg; - background: transparent; -} - -QLabel[TitleLabel="true"] { - padding-top: 5px; - padding-bottom: 5px; - color: @label_titlelabel_fg; - background-color: @label_titlelabel_bg; -} - -QLabel[ColorRedLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #D32F2F; -} - -QLabel[ColorGreenLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #388E3C; -} - -QLabel[ColorGreyLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #616161; -} - -QLabel[ColorTealLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #00796B; -} - -QLabel[MenuSeparator="true"] { - padding-top: 5px; - padding-bottom: 5px; - margin-top: 3px; - font: italic; - border-top: 1px solid @menu_separator_bg -} - -VVimIndicator QLabel[VimIndicatorKeyLabel="true"] { - font: bold; - color: @vim_indicator_key_label_fg; - background: transparent; -} - -VVimIndicator QLabel[VimIndicatorModeLabel="true"] { - padding: 0px 2px 0px 2px; - font: bold; - color: @vim_indicator_mode_label_fg; - /* background color will be controlled by the code. */ -} - -VTabIndicator QLabel[TabIndicatorLabel="true"] { - color: @tab_indicator_label_fg; - background: transparent; -} -/* End QLabel */ - -/* QLineEdit */ -QLineEdit { - border: 1px solid @lineedit_border; - padding: 3px; - color: @lineedit_fg; - background: @lineedit_bg; - selection-color: @lineedit_selection_fg; - selection-background-color: @lineedit_selection_bg; -} - -QLineEdit:focus { - border: 2px solid @lineedit_focus_border; - background: @lineedit_focus_bg; -} - -QLineEdit[VimCommandLine="true"] { - padding: 0px; - margin: 0px; - border: none; - color: @lineedit_fg; - background: @lineedit_bg; -} -/* End QLineEdit */ - -/* QPlainTextEdit QTextEdit */ -QPlainTextEdit[LineEdit="true"], QTextEdit[LineEdit="true"] { - border: 1px solid @lineedit_border; - padding: 3px; - color: @lineedit_fg; - background: @lineedit_bg; - selection-color: @lineedit_selection_fg; - selection-background-color: @lineedit_selection_bg; -} - -QPlainTextEdit[LineEdit="true"]:focus, QTextEdit[LineEdit="true"]:focus { - border: 2px solid @lineedit_focus_border; - background: @lineedit_focus_bg; -} -/* End QPlainTextEdit QTextEdit */ - -/* QTabWidget */ -QTabWidget { - border: none; -} - -QTabWidget::pane { - border: none; -} -/* End QTabWidget */ - -/* QTabBar */ -QTabBar::tab { - color: @tabbar_fg; - background: @tabbar_bg; - border: 1px solid @tabbar_border; - border-bottom: none; - border-top: none; - padding: 2px; -} - -QTabBar::tab:selected { - color: @tabbar_selected_fg; - background: @tabbar_selected_bg; - border-top: 3px solid @master_bg; -} - -QTabBar::tab:hover { - color: @tabbar_hover_fg; - background: @tabbar_hover_bg; -} - -QTabBar::close-button { - image: url(close_grey.svg); -} - -QTabBar::close-button:hover { - image: url(close.svg); -} - -QTabBar::close-button:focus { - image: url(close.svg); -} - -QTabBar::scroller { - width: 20px; -} - -QTabBar QToolButton { - border: none; -} - -QTabBar QToolButton::right-arrow:enabled { - image: url(right.svg); -} - -QTabBar QToolButton::left-arrow:enabled { - image: url(left.svg); -} - -QTabBar QToolButton::right-arrow:disabled { - image: url(right_disabled.svg); -} - -QTabBar QToolButton::left-arrow:disabled { - image: url(left_disabled.svg); -} -/* End QTabBar */ - -VSelectorItemWidget QLabel[SelectorItemShortcutLabel="true"] { - font: bold; - border: 2px solid @selectoritem_border; - padding: 3px; - border-radius: 5px; - background-color: @selectoritem_bg; - color: @selectoritem_fg; -} - -VInsertSelector { - border: none; - background: @insertselector_bg; -} - -/* QTreeView */ -QTreeView { - color: @treeview_fg; - background: @treeview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QTreeView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QTreeView::item:hover { - color: @treeview_item_hover_fg; - background: @treeview_item_hover_bg; -} - -QTreeView::item:selected { - color: @treeview_item_selected_fg; - background: @treeview_item_selected_bg; -} - -QTreeView::item:selected:active { - color: @treeview_item_selected_active_fg; - background: @treeview_item_selected_active_bg; -} - -QTreeView::item:selected:!active { - color: @treeview_item_selected_inactive_fg; - background: @treeview_item_selected_inactive_bg; -} - - -/* -QTreeView::branch:has-siblings:!adjoins-item { - border-image: url(line.svg) 0; -} - -QTreeView::branch:has-siblings:adjoins-item { - border-image: url(branch_more.svg) 0; -} - -QTreeView::branch:!has-children:!has-siblings:adjoins-item { - border-image: url(branch_end.svg) 0; -} - -QTreeView::branch:has-children:!has-siblings:closed, -QTreeView::branch:closed:has-children:has-siblings { - border-image: none; - image: url(branch_closed.svg); -} - -QTreeView::branch:open:has-children:!has-siblings, -QTreeView::branch:open:has-children:has-siblings { - border-image: none; - image: url(branch_open.svg); -} - - -*/ -/* End QTreeView */ - -/* QListView */ -QListView { - color: @listview_fg; - background: @listview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QListView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QListView::item:hover { - color: @listview_item_hover_fg; - background: @listview_item_hover_bg; -} - -QListView::item:selected { - color: @listview_item_selected_fg; - background: @listview_item_selected_bg; -} - -QListView::item:selected:active { - color: @listview_item_selected_active_fg; - background: @listview_item_selected_active_bg; -} - -QListView::item:selected:!active { - color: @listview_item_selected_inactive_fg; - background: @listview_item_selected_inactive_bg; -} -/* End QListView */ - -/* QSplitter */ -QSplitter { - border: none; -} - -QSplitter::handle { - background-color: @splitter_handle_bg; -} - -QSplitter::handle:vertical { - height: 2px; -} - -QSplitter::handle:horizontal { - width: 2px; -} - -QSplitter#MainSplitter { - border: none; -} -/* End QSplitter */ - -/* QStatusBar */ -QStatusBar { - color: @statusbar_fg; - background: @statusbar_bg; -} -/* End QStatusBar */ - -QWidget[MainEditor="true"] { - border: none; -} - -QDialog { - color: @base_fg; - background: @base_bg; -} - -/* QScrollBar */ -QScrollBar::add-page, QScrollBar::sub-page { - background: @scrollbar_page_bg; -} - -QScrollBar:vertical { - background: @scrollbar_bg; - width: 16px; - margin: 16px 0px 16px 0px; - padding: 0px 2px 0px 2px; - border: none; -} - -QScrollBar::handle:vertical { - background: @scrollbar_handle_bg; - min-height: 16px; -} - -QScrollBar::handle:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:vertical { - border: none; - background: @scrollbar_bg; - width: 16px; - height: 16px; - subcontrol-position: bottom; - subcontrol-origin: margin; -} - -QScrollBar::add-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:vertical { - border: none; - background: @scrollbar_bg; - width: 16px; - height: 16px; - subcontrol-position: top; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::down-arrow:vertical { - image: url(down.svg); - width: 16px; - height: 16px; -} - -QScrollBar::up-arrow:vertical { - image: url(up.svg); - width: 16px; - height: 16px; -} - -QScrollBar:horizontal { - background: @scrollbar_bg; - height: 16px; - margin: 0px 16px 0px 16px; - padding: 2px 0px 2px 0px; - border: none; -} - -QScrollBar::handle:horizontal { - background: @scrollbar_handle_bg; - min-width: 16px; -} - -QScrollBar::handle:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:horizontal { - border: none; - background: @scrollbar_bg; - width: 16px; - height: 16px; - subcontrol-position: right; - subcontrol-origin: margin; -} - -QScrollBar::add-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:horizontal { - border: none; - background: @scrollbar_bg; - width: 16px; - height: 16px; - subcontrol-position: left; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::right-arrow:horizontal { - image: url(right.svg); - width: 16px; - height: 16px; -} - -QScrollBar::left-arrow:horizontal { - image: url(left.svg); - width: 16px; - height: 16px; -} -/* End QScrollBar */ - -/* QCheckBox */ -QCheckBox { - spacing: 5px; -} - -QCheckBox::indicator { - width: 20px; - height: 20px; -} - -QCheckBox::indicator:unchecked { - image: url(checkbox_unchecked.svg); -} - -QCheckBox::indicator:unchecked:hover { - background: @checkbox_indicator_hover_bg; -} - -QCheckBox::indicator:unchecked:pressed { - background: @checkbox_indicator_pressed_bg; -} - -QCheckBox::indicator:checked { - image: url(checkbox_checked.svg); -} - -QCheckBox::indicator:checked:hover { - background: @checkbox_indicator_hover_bg; -} - -QCheckBox::indicator:checked:pressed { - background: @checkbox_indicator_pressed_bg; -} - -QCheckBox::indicator:indeterminate:hover { - background: @checkbox_indicator_hover_bg; -} - -QCheckBox::indicator:indeterminate:pressed { - background: @checkbox_indicator_pressed_bg; -} -/* End QCheckBox */ - -/* QRadioButton */ -QRadioButton { - spacing: 5px; -} - -QRadioButton::indicator { - width: 20px; - height: 20px; -} - -QRadioButton::indicator:unchecked { - image: url(radiobutton_unchecked.svg); -} - -QRadioButton::indicator:unchecked:hover { - background: @radiobutton_indicator_hover_bg; -} - -QRadioButton::indicator:unchecked:pressed { - background: @radiobutton_indicator_pressed_bg; -} - -QRadioButton::indicator:checked { - image: url(radiobutton_checked.svg); -} - -QRadioButton::indicator:checked:hover { - background: @radiobutton_indicator_hover_bg; -} - -QRadioButton::indicator:checked:pressed { - background: @radiobutton_indicator_pressed_bg; -} -/* End QRadioButton */ - -/* QSpinBox */ -QSpinBox, QDoubleSpinBox { - border: 1px solid @spinbox_border; - color: @spinbox_fg; - background: @spinbox_bg; - padding-right: 25px; - min-height: 25px; - selection-color: @spinbox_selection_fg; - selection-background-color: @spinbox_selection_bg; -} - -QSpinBox:focus, QDoubleSpinBox::focus { - border: 2px solid @spinbox_focus_border; - background: @spinbox_focus_bg; -} - -QSpinBox::up-button, QDoubleSpinBox::up-button { - subcontrol-origin: border; - subcontrol-position: top right; /* position at the top right corner */ - width: 25px; - border: none; - background: transparent; -} - -QSpinBox::up-button:hover, QDoubleSpinBox::up-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::up-button:pressed, QDoubleSpinBox::up-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::up-arrow, QDoubleSpinBox::up-arrow { - image: url(up.svg); - width: 12px; - height: 12px; -} - -QSpinBox::up-arrow:disabled, QSpinBox::up-arrow:off, QDoubleSpinBox::up-arrow:disabled, QDoubleSpinBox::up-arrow:off { - image: url(up_disabled.svg); -} - -QSpinBox::down-button, QDoubleSpinBox::down-button { - subcontrol-origin: border; - subcontrol-position: bottom right; /* position at the top right corner */ - width: 25px; - border: none; - background: transparent; -} - -QSpinBox::down-button:hover, QDoubleSpinBox::down-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::down-button:pressed, QDoubleSpinBox::down-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::down-arrow, QDoubleSpinBox::down-arrow { - image: url(down.svg); - width: 12px; - height: 12px; -} - -QSpinBox::down-arrow:disabled, QSpinBox::down-arrow:off, QDoubleSpinBox::down-arrow:disabled, QDoubleSpinBox::down-arrow:off { - image: url(down_disabled.svg); -} -/* End QSpinBox */ - -/* QHeaderView */ -QHeaderView::section { - background: @headerview_bg; - color: @headerview_fg; - padding-left: 4px; - border: none; - border-left: 1px solid @headerview_border; - border-bottom: 1px solid @headerview_border; -} - -QHeaderView::section:checked -{ - color: @headerview_checked_fg; - background: @headerview_checked_bg; -} - -/* style the sort indicator */ -QHeaderView::down-arrow { - image: url(down.svg); -} - -QHeaderView::up-arrow { - image: url(up.svg); -} -/* End QHeaderView */ - -QWidget#FindReplaceTitleWidget { - background: @title_bg; -} diff --git a/src/resources/themes/v_material/v_material_codeblock.css b/src/resources/themes/v_material/v_material_codeblock.css deleted file mode 100644 index e8191399..00000000 --- a/src/resources/themes/v_material/v_material_codeblock.css +++ /dev/null @@ -1,96 +0,0 @@ -/* - -Atom One Light by Daniel Gamage -Original One Light Syntax theme from https://github.com/atom/one-light-syntax - -base: #fafafa -mono-1: #383a42 -mono-2: #686b77 -mono-3: #a0a1a7 -hue-1: #0184bb -hue-2: #4078f2 -hue-3: #a626a4 -hue-4: #50a14f -hue-5: #e45649 -hue-5-2: #c91243 -hue-6: #986801 -hue-6-2: #c18401 - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #eeffff; - /*background: #1a2226;*/ -} - -.hljs-comment, -.hljs-quote { - color: #546e7a; - font-style: italic; -} - -.hljs-doctag, -.hljs-keyword, -.hljs-formula { - color: #c792ea; -} - -.hljs-section, -.hljs-name, -.hljs-selector-tag, -.hljs-deletion, -.hljs-subst { - color: #c3e88d; -} - -.hljs-literal { - color: #0184bb; -} - -.hljs-string, -.hljs-regexp, -.hljs-addition, -.hljs-attribute, -.hljs-meta-string { - color: #c3e176; -} - -.hljs-built_in, -.hljs-class .hljs-title { - color: #ffcb6b; -} - -.hljs-attr, -.hljs-variable, -.hljs-template-variable, -.hljs-type, -.hljs-selector-class, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-number { - color: #f78c6c; -} - -.hljs-symbol, -.hljs-bullet, -.hljs-link, -.hljs-meta, -.hljs-selector-id, -.hljs-title { - color: #4078f2; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} - -.hljs-link { - text-decoration: underline; -} diff --git a/src/resources/themes/v_moonlight/arrow_dropdown.svg b/src/resources/themes/v_moonlight/arrow_dropdown.svg deleted file mode 100644 index b831fa00..00000000 --- a/src/resources/themes/v_moonlight/arrow_dropdown.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/src/resources/themes/v_moonlight/branch_closed.svg b/src/resources/themes/v_moonlight/branch_closed.svg deleted file mode 100644 index 796782cb..00000000 --- a/src/resources/themes/v_moonlight/branch_closed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/branch_open.svg b/src/resources/themes/v_moonlight/branch_open.svg deleted file mode 100644 index 3212fbf9..00000000 --- a/src/resources/themes/v_moonlight/branch_open.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/checkbox_checked.svg b/src/resources/themes/v_moonlight/checkbox_checked.svg deleted file mode 100644 index 6efbccc4..00000000 --- a/src/resources/themes/v_moonlight/checkbox_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_moonlight/checkbox_unchecked.svg b/src/resources/themes/v_moonlight/checkbox_unchecked.svg deleted file mode 100644 index c9a55295..00000000 --- a/src/resources/themes/v_moonlight/checkbox_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_moonlight/close.svg b/src/resources/themes/v_moonlight/close.svg deleted file mode 100644 index 2ff42f1a..00000000 --- a/src/resources/themes/v_moonlight/close.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_moonlight/close_grey.svg b/src/resources/themes/v_moonlight/close_grey.svg deleted file mode 100644 index 0e2cd92c..00000000 --- a/src/resources/themes/v_moonlight/close_grey.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_moonlight/down.svg b/src/resources/themes/v_moonlight/down.svg deleted file mode 100644 index 56f2a45d..00000000 --- a/src/resources/themes/v_moonlight/down.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/down_disabled.svg b/src/resources/themes/v_moonlight/down_disabled.svg deleted file mode 100644 index e6cb5fa8..00000000 --- a/src/resources/themes/v_moonlight/down_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/float.svg b/src/resources/themes/v_moonlight/float.svg deleted file mode 100644 index 28cc666a..00000000 --- a/src/resources/themes/v_moonlight/float.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/themes/v_moonlight/left.svg b/src/resources/themes/v_moonlight/left.svg deleted file mode 100644 index 0e339476..00000000 --- a/src/resources/themes/v_moonlight/left.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/left_disabled.svg b/src/resources/themes/v_moonlight/left_disabled.svg deleted file mode 100644 index fd4937e8..00000000 --- a/src/resources/themes/v_moonlight/left_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/menu_checkbox.svg b/src/resources/themes/v_moonlight/menu_checkbox.svg deleted file mode 100644 index 3acab8ad..00000000 --- a/src/resources/themes/v_moonlight/menu_checkbox.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_moonlight/menu_radiobutton.svg b/src/resources/themes/v_moonlight/menu_radiobutton.svg deleted file mode 100644 index fcb32f20..00000000 --- a/src/resources/themes/v_moonlight/menu_radiobutton.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_moonlight/radiobutton_checked.svg b/src/resources/themes/v_moonlight/radiobutton_checked.svg deleted file mode 100644 index 50642a94..00000000 --- a/src/resources/themes/v_moonlight/radiobutton_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_moonlight/radiobutton_unchecked.svg b/src/resources/themes/v_moonlight/radiobutton_unchecked.svg deleted file mode 100644 index eccd8165..00000000 --- a/src/resources/themes/v_moonlight/radiobutton_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_moonlight/right.svg b/src/resources/themes/v_moonlight/right.svg deleted file mode 100644 index 796782cb..00000000 --- a/src/resources/themes/v_moonlight/right.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/right_disabled.svg b/src/resources/themes/v_moonlight/right_disabled.svg deleted file mode 100644 index 175f2ff3..00000000 --- a/src/resources/themes/v_moonlight/right_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/up.svg b/src/resources/themes/v_moonlight/up.svg deleted file mode 100644 index cb37cc73..00000000 --- a/src/resources/themes/v_moonlight/up.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/up_disabled.svg b/src/resources/themes/v_moonlight/up_disabled.svg deleted file mode 100644 index 68f1d067..00000000 --- a/src/resources/themes/v_moonlight/up_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/v_moonlight.css b/src/resources/themes/v_moonlight/v_moonlight.css deleted file mode 100644 index ec81d9c8..00000000 --- a/src/resources/themes/v_moonlight/v_moonlight.css +++ /dev/null @@ -1,296 +0,0 @@ -body { - margin: 0 auto; - font-family: Helvetica, sans-serif, Tahoma, Arial, Verdana, Geneva, Georgia, Palatino, "Times New Roman", "Hiragino Sans GB", "冬青黑体", "Microsoft YaHei", "微软雅黑", "Microsoft YaHei UI", "WenQuanYi Micro Hei", "文泉驿雅黑", Dengxian, "等线体", STXihei, "华文细黑", "Liberation Sans", "Droid Sans", NSimSun, "新宋体", SimSun, "宋体"; - color: #ABB2BF; - line-height: 1; - padding: 30px; - background: #282C34; -} - -h1, h2, h3, h4, h5, h6 { - color: #E06C75; - font-weight: bold; - margin-bottom: 24px; - padding: 0; -} - -p { - padding: 0; -} - -h1 { - font-size: 36px; -} - -h2 { - font-size: 30px; -} - -h3 { - font-size: 26px; -} - -h4 { - font-size: 22px; -} - -h5 { - font-size: 20px; -} - -h6 { - font-size: 18px; -} - -a { - color: #61AFEF; - margin: 0; - padding: 0; - vertical-align: baseline; - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - -a:visited { - color: purple; -} - -ul, ol { - padding: 0; - padding-left: 24px; -} - -li { - line-height: 24px; -} - -li ul, li ul { - margin-left: 24px; -} - -p, ul, ol { - font-size: 16px; - line-height: 24px; -} - -pre { - display: block; - overflow-y: hidden; - overflow-x: auto; -} - -code { - font-family: Consolas, Monaco, Andale Mono, Monospace, Courier New; - line-height: 1.5; - font-size: 14px; - color: #98C379; -} - -pre code { - margin: 0; - padding: 0; - border: none; - color: #98C379; -} - -aside { - display: block; - float: right; - width: 390px; -} - -blockquote { - color: #5C6370; - border-left:.5em solid #5C6370; - padding: 0 2em; - margin-left:0; -} - -blockquote p { - color: #5C6370; -} - -hr { - display: block; - text-align: left; - margin: 1em 0; - border: none; - height: 2px; - background: #373E47; -} - -table { - padding: 0; - border-collapse: collapse; -} - -table tr { - border-top: 1px solid #373E47; - margin: 0; - padding: 0; -} - -table tr th { - font-weight: bold; - border: 1px solid #373E47; - margin: 0; - padding: 6px 13px; -} - -table tr td { - border: 1px solid #373E47; - margin: 0; - padding: 6px 13px; -} - -table tr th :first-child, table tr td :first-child { - margin-top: 0; -} - -table tr th :last-child, table tr td :last-child { - margin-bottom: 0; -} - -div.mermaid-diagram { - overflow-y: hidden; - background: #7D879B; - color: #6C6C6C; -} - -pre.mermaid-diagram { - overflow-y: hidden; -} - -div.flowchart-diagram { - overflow-y: hidden; - background: #7D879B; - color: #6C6C6C; -} - -pre.flowchart-diagram { - overflow-y: hidden; -} - -.img-package { - text-align: center; -} - -img.img-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -div.img-caption { - min-width: 20%; - max-width: 80%; - display: inline-block; - padding: 10px; - margin: 0 auto; - border-bottom: 1px solid #373E47; - color: #ABB2BF; - text-align: center; - line-height: 1.5; -} - -/* For Highlight.js Line Number */ -table.hljs-ln tr { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td.hljs-ln-numbers { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - - text-align: center; - color: #5C6370; - border-right: 1px solid #373E47; - vertical-align: top; - padding-right: 5px; -} - -table.hljs-ln tr td.hljs-ln-code { - padding-left: 10px; -} - -::-webkit-scrollbar { - background-color: #21252B; - width: 14px; - height: 14px; - border: none; -} - -::-webkit-scrollbar-corner { - background-color: #21252B; -} - -::-webkit-scrollbar-button { - /* This selector affects the styling of both the up & down and left & right buttons of a scrollbar */ - height: 14px; - width: 14px; - background-color: #21252B; -} - -::-webkit-scrollbar-button:hover { - background-color: #424A56; -} - -::-webkit-scrollbar-button:active { - background-color: #31363F; -} - -::-webkit-scrollbar-track { - /* This selector affects the styling of the area in the scrollbar between the two buttons */ - background-color: #21252B; -} - -::-webkit-scrollbar-thumb { - /* This selector affects the styling of draggable element of the scollbar */ - border: none; - background-color: #353B45; -} - -::-webkit-scrollbar-thumb:hover { - background-color: #424A56; -} - -::-webkit-scrollbar-thumb:active { - background-color: #31363F; -} - -::-webkit-scrollbar-button:horizontal:increment { - background-image: url(right.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:horizontal:decrement { - background-image: url(left.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:vertical:increment { - background-image: url(down.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:vertical:decrement { - background-image: url(up.svg); - background-repeat: no-repeat; - background-size: contain; -} diff --git a/src/resources/themes/v_moonlight/v_moonlight.mdhl b/src/resources/themes/v_moonlight/v_moonlight.mdhl deleted file mode 100644 index e391e00c..00000000 --- a/src/resources/themes/v_moonlight/v_moonlight.mdhl +++ /dev/null @@ -1,169 +0,0 @@ -# This is the default markdown styles used for Peg-Markdown-Highlight -# created by Le Tan(tamlokveer@gmail.com). -# For a complete description of the syntax, please refer to the original -# documentation of the style parser -# [The Syntax of PEG Markdown Highlight Stylesheets](http://hasseg.org/peg-markdown-highlight/docs/stylesheet_syntax.html). -# VNote adds some styles in the syntax which will be marked [VNote] in the comment. -# -# Note: Empty lines within a section is NOT allowed. -# Note: Do NOT modify this file directly. Copy it and tune your own style! - -editor -# QTextEdit just choose the first available font, so specify the Chinese fonts first -# Do not use "" to quote the name -font-family: Hiragino Sans GB, 冬青黑体, Microsoft YaHei, 微软雅黑, Microsoft YaHei UI, WenQuanYi Micro Hei, 文泉驿雅黑, Dengxian, 等线体, STXihei, 华文细黑, Liberation Sans, Droid Sans, NSimSun, 新宋体, SimSun, 宋体, Helvetica, sans-serif, Tahoma, Arial, Verdana, Geneva, Georgia, Times New Roman -font-size: 12 -foreground: abb2bf -background: 282c34 -# [VNote] Style for trailing space -trailing-space: 636d81 -# [VNote] Style for line number -line-number-background: 2c313a -line-number-foreground: 5c6370 -# [VNote] Style for selected word highlight -selected-word-background: 454bb2 -# [VNote] Style for searched word highlight -searched-word-background: 424956 -# [VNote] Style for searched word under cursor highlight -searched-word-cursor-background: 596173 -# [VNote] Style for incremental searched word highlight -incremental-searched-word-background: 596173 -# [VNote] Style for color column in fenced code block -color-column-background: c9302c -color-column-foreground: eeeeee -# [VNote} Style for preview image line -preview-image-line-foreground: 6f5799 - -editor-selection -foreground: dadada -background: 1e88e5 - -editor-current-line -background: 353d49 -# [VNote] Vim insert mode cursor line background -vim-insert-background: 353d49 -# [VNote] Vim normal mode cursor line background -vim-normal-background: 373c47 -# [VNote] Vim visual mode cursor line background -vim-visual-background: 105fa2 -# [VNote] Vim replace mode cursor line background -vim-replace-background: 2f3377 - -H1 -foreground: e06c75 -font-style: bold -font-size: +8 - -H2 -foreground: e06c75 -font-style: bold -font-size: +6 - -H3 -foreground: e06c75 -font-style: bold -font-size: +4 - -H4 -foreground: e06c75 -font-style: bold -font-size: +2 - -H5 -foreground: e06c75 -font-style: bold -font-size: +2 - -H6 -foreground: e06c75 -font-style: bold -font-size: +2 - -HRULE -foreground: 8b90f3 - -LIST_BULLET -foreground: e06c75 -font-style: bold -font-size: +2 - -LIST_ENUMERATOR -foreground: e06c75 - -LINK -foreground: 61afef - -AUTO_LINK_URL -foreground: 61afef - -AUTO_LINK_EMAIL -foreground: 61afef - -IMAGE -foreground: 4883b3 - -REFERENCE -foreground: 56b6c2 - -CODE -foreground: 98c379 -font-family: Consolas, Monaco, Andale Mono, Monospace, Courier New - -EMPH -font-style: italic - -STRONG -font-style: bold - -HTML_ENTITY -foreground: abb2bf - -COMMENT -foreground: 5c6370 - -VERBATIM -foreground: 98c379 -font-family: Consolas, Monaco, Andale Mono, Monospace, Courier New -# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, color) -# The last occurence of the same attribute takes effect -# Could specify multiple attribute in one line -hljs-comment: 5c6370 -hljs-quote: 5c6370 -hljs-doctag: c678dd -hljs-keyword: c678dd -hljs-formula: c678dd -hljs-section: e06c75 -hljs-name: e06c75 -hljs-selector-tag: e06c75 -hljs-deletion: e06c75 -hljs-subst: e06c75 -hljs-literal: 56b6c2 -hljs-string: 98c379 -hljs-regexp: 98c379 -hljs-addition: 98c379 -hljs-attribute: 98c379 -hljs-meta-string: 98c379 -hljs-built_in: e6c07b -hljs-class: e6c07b -hljs-attr: d19a66 -hljs-variable: d19a66 -hljs-template-variable: d19a66 -hljs-type: d19a66 -hljs-selector-class: d19a66 -hljs-selector-attr: d19a66 -hljs-selector-pseudo: d19a66 -hljs-number: d19a66 -hljs-symbol: 61aeee -hljs-link: underlined, 61aeee -hljs-bullet: 61aeee -hljs-meta: 61aeee -hljs-selector-id: 61aeee -hljs-title: bold, 61aeee -hljs-emphasis: italic -hljs-strong: bold - -BLOCKQUOTE -foreground: 5c6370 - -STRIKE -strike-color: 586e75 diff --git a/src/resources/themes/v_moonlight/v_moonlight.palette b/src/resources/themes/v_moonlight/v_moonlight.palette deleted file mode 100644 index 2373a66c..00000000 --- a/src/resources/themes/v_moonlight/v_moonlight.palette +++ /dev/null @@ -1,343 +0,0 @@ -; File path could be absolute path or relative path (related to this file). -; Use @color_tag to reference a style. - -[metadata] -qss_file=v_moonlight.qss -mdhl_file=v_moonlight.mdhl -css_file=v_moonlight.css -codeblock_css_file=v_moonlight_codeblock.css - -[phony] -; Abstract color attributes. -master_fg=@edit_fg -master_bg=#00695C -master_light_bg=#4DB6AC -master_drak_bg=#004D40 -master_focus_bg=#00796B -master_hover_bg=#00796B -master_pressed_bg=#004D40 - -base_fg=#9DA5B4 -base_bg=#21252B - -main_fg=@base_fg -main_bg=#base_bg - -title_fg=@base_fg -title_bg=@base_bg - -disabled_fg=#4D5765 - -content_fg=@base_fg -content_bg=@base_bg - -border_bg=#181A1F - -separator_bg=#373E47 - -hover_fg=#D7DAE0 -hover_bg=#31363F - -selected_fg=#FFFFFF -selected_bg=#3A3F4B - -active_fg=@selected_fg -active_bg=@selected_bg - -inactive_fg=@hover_fg -inactive_bg=#4D5465 - -focus_fg=@hover_fg -focus_bg=@hover_bg - -pressed_fg=@hover_fg -pressed_bg=#2C303A - -edit_fg=#D7DAE0 -edit_bg=#282C34 -edit_focus_bg=#1B1D23 -edit_focus_border=@master_bg -edit_selection_fg=@edit_fg -edit_selection_bg=#4D5565 - -icon_fg=#9EA5B4 -icon_disabled_fg=@disabled_fg - -danger_fg=#F5F5F5 -danger_bg=#C9302C -danger_focus_bg=#D9534F -danger_hover_bg=#D9534F -danger_pressed_bg=#AC2925 - -[soft_defined] -; VAvatar. -avatar_border_bg=#7D879B -avatar_fg=@base_bg -avatar_bg=@base_fg -; The border background color of the avatar when Captain mode is triggered. -avatar_captain_mode_border_bg=@master_bg - -; Style of the label in Navigation mode. -navigation_label_fg=@master_fg -navigation_label_bg=@master_bg - -; Style of the bubble of VButtonWithWidget. -bubble_fg=@master_fg -bubble_bg=@master_bg - -; Icons' foreground. -danger_icon_fg=@danger_bg -item_icon_fg=@icon_fg -title_icon_fg=@icon_fg - -; VVimIndicator. -vim_indicator_key_label_fg=@base_fg -vim_indicator_mode_label_fg=@base_fg -vim_indicator_cmd_edit_pending_bg=@selected_bg - -; VTabIndicator. -tab_indicator_label_fg=@base_fg - -; Html template. -template_title_flash_light_fg=@master_light_bg -template_title_flash_dark_fg=@master_bg - -[widgets] -; Widget color attributes. - -; QWidget. -widget_fg=@base_fg - -; Separator of dock widgets. -dock_separator_bg=@border_bg -dock_separator_hover_bg=@border_bg - -; Menubar. -menubar_bg=@main_bg -menubar_fg=@main_fg -menubar_item_selected_bg=@selected_bg - -; Menu. -menu_bg=@base_bg -menu_fg=@base_fg -menu_item_disabled_fg=@disabled_fg -menu_item_selected_fg=@selected_fg -menu_item_selected_bg=@selected_bg -menu_separator_bg=@separator_bg -menu_icon_fg=@icon_fg -menu_icon_danger_fg=@danger_icon_fg - -; Tooltip. -tooltip_bg=@master_bg -tooltip_fg=@master_fg - -; Toolbar. -toolbar_bg=@main_bg -toolbar_separator_bg=@separator_bg -toolbutton_hover_bg=@hover_bg -toolbutton_pressed_bg=@pressed_bg -toolbutton_checked_bg=@selected_bg -toolbutton_icon_fg=@icon_fg -toolbutton_icon_danger_fg=@danger_icon_fg - -; Toolbox. -toolbox_icon_fg=@master_bg -toolbox_icon_active_fg=@master_fg -toolbox_title_border=@master_bg - -; Dockwidget. -dockwidget_title_fg=@title_fg -dockwidget_title_bg=@title_bg -dockwidget_button_hover_bg=@hover_bg - -; PushButton. -pushbutton_fg=@base_fg -pushbutton_bg=transparent -pushbutton_border=@border_bg -pushbutton_pressed_bg=@pressed_bg -pushbutton_focus_bg=@focus_bg -pushbutton_checked_bg=@selected_bg -pushbutton_hover_bg=@hover_bg -pushbutton_default_border=@master_bg -pushbutton_disabled_fg=@disabled_fg -pushbutton_disabled_bg=@pushbutton_bg - -pushbutton_specialbtn_fg=@master_fg -pushbutton_specialbtn_bg=@master_bg -pushbutton_specialbtn_focus_bg=@master_focus_bg -pushbutton_specialbtn_hover_bg=@master_hover_bg -pushbutton_specialbtn_checked_bg=@master_focus_bg -pushbutton_specialbtn_pressed_bg=@master_pressed_bg - -pushbutton_cornerbtn_hover_bg=@hover_bg -pushbutton_cornerbtn_focus_bg=@focus_bg -pushbutton_cornerbtn_pressed_bg=@pressed_bg - -pushbutton_statusbtn_hover_bg=@hover_bg -pushbutton_statusbtn_focus_bg=@focus_bg -pushbutton_statusbtn_pressed_bg=@pressed_bg - -pushbutton_flatbtn_hover_bg=@hover_bg -pushbutton_flatbtn_focus_bg=@focus_bg -pushbutton_flatbtn_pressed_bg=@pressed_bg - -pushbutton_selectionbtn_hover_bg=@hover_bg -pushbutton_selectionbtn_focus_bg=@focus_bg -pushbutton_selectionbtn_pressed_bg=@pressed_bg - -pushbutton_titlebtn_bg=@title_bg -pushbutton_titlebtn_hover_bg=@hover_bg -pushbutton_titlebtn_focus_bg=@focus_bg -pushbutton_titlebtn_pressed_bg=@pressed_bg - -pushbutton_dangerbtn_fg=@danger_fg -pushbutton_dangerbtn_bg=@danger_bg -pushbutton_dangerbtn_hover_bg=@danger_hover_bg -pushbutton_dangerbtn_focus_bg=@danger_focus_bg -pushbutton_dangerbtn_pressed_bg=@danger_pressed_bg - -pushbutton_toolboxbtn_active_fg=@master_fg -pushbutton_toolboxbtn_active_bg=@master_bg -pushbutton_toolboxbtn_active_focus_bg=@master_focus_bg -pushbutton_toolboxbtn_active_hover_bg=@master_hover_bg -pushbutton_toolboxbtn_active_pressed_bg=@master_pressed_bg - -button_icon_fg=@icon_fg -button_icon_danger_fg=@danger_icon_fg - -; ComboBox. -combobox_border=@border_bg -combobox_fg=@content_fg -combobox_bg=@content_bg -combobox_view_border=@border_bg -combobox_view_selected_bg=@selected_bg -combobox_view_selected_fg=@selected_fg -combobox_view_item_hover_fg=@hover_fg -combobox_view_item_hover_bg=@hover_bg -combobox_focus_bg=@edit_focus_bg -combobox_focus_border=@edit_focus_border -combobox_item_icon_fg=@item_icon_fg - -combobox_notebookselector_fg=@master_bg -combobox_notebookselector_bg=@combobox_bg -combobox_notebookselector_border=@master_bg -combobox_notebookselector_hover_fg=@master_bg -combobox_notebookselector_hover_bg=@hover_bg -combobox_notebookselector_focus_fg=@master_bg -combobox_notebookselector_focus_bg=@focus_bg - -; Label. -label_fg=@base_fg -label_titlelabel_fg=@title_fg -label_titlelabel_bg=@title_bg - -; LineEdit. -lineedit_border=@border_bg -lineedit_fg=@edit_fg -lineedit_bg=@edit_bg -lineedit_focus_bg=@edit_focus_bg -lineedit_focus_border=@edit_focus_border -lineedit_selection_fg=@edit_selection_fg -lineedit_selection_bg=@edit_selection_bg - -; TabWidget. -tabwidget_pane_border=@selected_bg - -; TabBar. -tabbar_fg=@base_fg -tabbar_bg=@base_bg -tabbar_border=@border_bg - -tabbar_selected_fg=@edit_fg -tabbar_selected_bg=@edit_bg -tabbar_selected_border=@border_bg - -tabbar_hover_fg=@hover_fg -tabbar_hover_bg=@hover_bg - -tabbar_icon_fg=@icon_fg -tabbar_icon_special_fg=@danger_bg - -; SelectorItem. -selectoritem_border=@master_bg -selectoritem_fg=@base_fg -selectoritem_bg=@base_bg - -; InsertSelector. -insertselector_bg=@base_bg - -; TreeView. -treeview_fg=@content_fg -treeview_bg=@content_bg -treeview_item_border_bg=@border_bg -treeview_item_hover_fg=@hover_fg -treeview_item_hover_bg=@hover_bg -treeview_item_selected_fg=@selected_fg -treeview_item_selected_bg=@selected_bg -treeview_item_selected_avtive_fg=@active_fg -treeview_item_selected_avtive_bg=@active_bg -treeview_item_selected_inactive_fg=@inactive_fg -treeview_item_selected_inactive_bg=@inactive_bg -treeview_item_icon_fg=@item_icon_fg - -; ListView. -listview_fg=@content_fg -listview_bg=@content_bg -listview_item_hover_fg=@hover_fg -listview_item_hover_bg=@hover_bg -listview_item_selected_fg=@selected_fg -listview_item_selected_bg=@selected_bg -listview_item_selected_avtive_fg=@active_fg -listview_item_selected_avtive_bg=@active_bg -listview_item_selected_inactive_fg=@inactive_fg -listview_item_selected_inactive_bg=@inactive_bg - -; Splitter. -splitter_handle_bg=@border_bg - -; StatusBar. -statusbar_fg=@main_fg -statusbar_bg=@main_bg -statusbar_border=@border_bg - -; ScrollBar. -scrollbar_bg=@base_bg -scrollbar_page_bg=transparent -scrollbar_handle_bg=#353B45 -scrollbar_handle_hover_bg=#424A56 -scrollbar_handle_pressed_bg=@hover_bg - -; VEditWindow. -editwindow_corner_icon_fg=@master_bg -editwindow_corner_icon_inactive_fg=@icon_fg - -; CheckBox. -checkbox_indicator_hover_bg=@hover_bg -checkbox_indicator_pressed_bg=@pressed_bg - -; RadioButton. -radiobutton_indicator_hover_bg=@hover_bg -radiobutton_indicator_pressed_bg=@pressed_bg - -; SpinBox. -spinbox_fg=@edit_fg -spinbox_bg=@edit_bg -spinbox_border=@border_bg -spinbox_selection_fg=@edit_selection_fg -spinbox_selection_bg=@edit_selection_bg -spinbox_focus_border=@edit_focus_border -spinbox_focus_bg=@edit_focus_bg -spinbox_button_hover_bg=@hover_bg -spinbox_button_pressed_bg=@pressed_bg - -; HeaderView. -headerview_bg=#30333D -headerview_fg=@base_fg -headerview_border=@border_bg -headerview_checked_fg=@selected_fg -headerview_checked_bg=@selected_bg - -; ProgressBar. -progressbar_bg=@edit_bg -progressbar_border_bg=@border_bg -progressbar_chunk_bg=@master_drak_bg diff --git a/src/resources/themes/v_moonlight/v_moonlight.qss b/src/resources/themes/v_moonlight/v_moonlight.qss deleted file mode 100644 index 2b9346ba..00000000 --- a/src/resources/themes/v_moonlight/v_moonlight.qss +++ /dev/null @@ -1,1284 +0,0 @@ -QToolTip -{ - border: none; - background: @tooltip_bg; - color: @tooltip_fg; -} - -/* QWidget */ -QWidget -{ - color: @widget_fg; - font-family: "Hiragino Sans GB", "冬青黑体", "Microsoft YaHei", "微软雅黑", "Microsoft YaHei UI", "WenQuanYi Micro Hei", "文泉驿雅黑", "Dengxian", "等线体", "STXihei", "华文细黑", "Liberation Sans", "Droid Sans", "NSimSun", "新宋体", "SimSun", "宋体", "Helvetica", "sans-serif", "Tahoma", "Arial", "Verdana", "Geneva", "Georgia", "Times New Roman"; -} - -QWidget[NotebookPanel="true"] { - padding-left: 3px; -} - -/* End QWidget */ - -/* QMainWindow */ -QMainWindow { - color: @base_fg; - background: @base_bg; -} - -QMainWindow::separator { - background: @dock_separator_bg; - width: 2px; - height: 2px; -} - -QMainWindow::separator:hover { - background: @dock_separator_hover_bg; -} -/* End QMainWindow */ - -QMenuBar { - border: none; - background: @menubar_bg; - color: @menubar_fg; -} - -QMenuBar::item:selected { - background: @menubar_item_selected_bg; -} - -/* QMenu */ -QMenu { - background: @menu_bg; - color: @menu_fg; - margin: 2px; -} - -QMenu::icon { - margin: 5px; -} - -QMenu::item { - padding: 5px 30px 5px 30px; - border: 1px solid transparent; -} - -QMenu::item:disabled { - color: @menu_item_disabled_fg; -} - -QMenu::item:selected { - color: @menu_item_selected_fg; - background: @menu_item_selected_bg; -} - -QMenu::icon:checked { /* appearance of a 'checked' icon */ - border: 2px solid @menu_fg; -} - -QMenu::separator { - height: 2px; - background: @menu_separator_bg; - margin-left: 10px; - margin-right: 5px; -} - -QMenu::indicator { - width: 20px; - height: 20px; -} - -QMenu::indicator:non-exclusive:unchecked { - image: none; -} - -QMenu::indicator:non-exclusive:checked { - image: url(menu_checkbox.svg); -} - -QMenu::indicator:exclusive:unchecked { - image: none; -} - -QMenu::indicator:exclusive:checked { - image: url(menu_radiobutton.svg); -} -/* End QMenu */ - -QToolBar { - border: none; - background: @toolbar_bg; -} - -QToolBar::separator { - width: 1px; - height: 1px; - border: none; - background: @toolbar_separator_bg; -} - -/* QToolButton */ -QToolButton { - border: none; - background: transparent; - margin: 1px 3px 1px 3px; - padding: 0px; -} - -QToolButton[popupMode="1"] { /* only for MenuButtonPopup */ - padding-right: 16px; /* make way for the popup button */ -} - -QToolButton[popupMode="2"] { /* only for InstantPopup */ - padding-right: 10px; /* make way for the popup button */ -} - -QToolButton:hover { - border:none; - background: @toolbutton_hover_bg; -} - -QToolButton:pressed { - background: @toolbutton_pressed_bg; -} - -QToolButton:checked { - background: @toolbutton_checked_bg; -} - -QToolButton:checked:hover { - background: @toolbutton_hover_bg; -} - -/* the subcontrols below are used only in the MenuButtonPopup mode */ -QToolButton::menu-button { - border: none; - width: 16px; -} - -QToolButton::menu-arrow { - image: url(arrow_dropdown.svg); - width: 16px; - height: 16px; -} -/* End QToolButton*/ - -/* DockWidget */ -QDockWidget { - color: @dockwidget_title_fg; - titlebar-close-icon: url(close.svg); - titlebar-normal-icon: url(float.svg); -} - -QDockWidget::Title { - background: @dockwidget_title_bg; - text-align: center left; -} - -QDockWidget::close-button, QDockWidget::float-button { - border: none; -} - -QDockWidget::close-button:hover, QDockWidget::float-button:hover { - background: @dockwidget_button_hover_bg; -} -/* End DockWidget */ - -/* QPushButton */ -QPushButton { - color: @pushbutton_fg; - background: @pushbutton_bg; - border: 1px solid @pushbutton_border; - padding: 3px; - min-width: 80px; -} - -QPushButton:focus { - background-color: @pushbutton_focus_bg; -} - -QPushButton:pressed { - background-color: @pushbutton_pressed_bg; -} - -QPushButton:checked { - background-color: @pushbutton_checked_bg; -} - -QPushButton:checked:hover { - background-color: @pushbutton_hover_bg; -} - -QPushButton:hover { - background-color: @pushbutton_hover_bg; -} - -QPushButton:flat { - border: none; -} - -QPushButton:default { - border-color: @pushbutton_default_border; -} - -QPushButton:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton::menu-indicator { - image: url(arrow_dropdown.svg); - width: 16px; - height: 16px; -} - -QPushButton[SpecialBtn="true"] { - color: @pushbutton_specialbtn_fg; - background: @pushbutton_specialbtn_bg; -} - -QPushButton[SpecialBtn="true"]:focus { - background-color: @pushbutton_specialbtn_focus_bg; -} - -QPushButton[SpecialBtn="true"]:pressed { - background-color: @pushbutton_specialbtn_pressed_bg; -} - -QPushButton[SpecialBtn="true"]:checked { - background-color: @pushbutton_specialbtn_checked_bg; -} - -QPushButton[SpecialBtn="true"]:checked:hover { - background-color: @pushbutton_specialbtn_hover_bg; -} - -QPushButton[SpecialBtn="true"]:hover { - background-color: @pushbutton_specialbtn_hover_bg; -} - -QPushButton[SpecialBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[CornerBtn="true"] { - padding: 4px -2px 4px -2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[CornerBtn="true"]::menu-indicator { - image: none; -} - -QPushButton[CornerBtn="true"]:hover { - background-color: @pushbutton_cornerbtn_hover_bg; -} - -QPushButton[CornerBtn="true"]:focus { - background-color: @pushbutton_cornerbtn_focus_bg; -} - -QPushButton[CornerBtn="true"]:pressed { - background-color: @pushbutton_cornerbtn_pressed_bg; -} - -QPushButton[CornerBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[StatusBtn="true"] { - font: bold; - padding: 0px 2px 0px 2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[StatusBtn="true"]:hover { - background-color: @pushbutton_statusbtn_hover_bg; -} - -QPushButton[StatusBtn="true"]:focus { - background-color: @pushbutton_statusbtn_focus_bg;; -} - -QPushButton[StatusBtn="true"]:pressed { - background-color: @pushbutton_statusbtn_pressed_bg; -} - -QPushButton[StatusBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[FlatBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[FlatBtn="true"]:hover { - background-color: @pushbutton_flatbtn_hover_bg; -} - -QPushButton[FlatBtn="true"]:focus { - background-color: @pushbutton_flatbtn_focus_bg; -} - -QPushButton[FlatBtn="true"]:pressed { - background-color: @pushbutton_flatbtn_pressed_bg; -} - -QPushButton[FlatBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[SelectionBtn="true"] { - padding: 4px 10px 4px 10px; - border: none; - background-color: transparent; - font-size: 15pt; - text-align: left; - min-width: -1; -} - -QPushButton[SelectionBtn="true"]:hover { - background-color: @pushbutton_selectionbtn_hover_bg; -} - -QPushButton[SelectionBtn="true"]:focus { - background-color: @pushbutton_selectionbtn_focus_bg; -} - -QPushButton[SelectionBtn="true"]:pressed { - background-color: @pushbutton_selectionbtn_pressed_bg; -} - -QPushButton[SelectionBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[TitleBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: @pushbutton_titlebtn_bg; - min-width: -1; -} - -QPushButton[TitleBtn="true"]:hover { - background-color: @pushbutton_titlebtn_hover_bg; -} - -QPushButton[TitleBtn="true"]:focus { - background-color: @pushbutton_titlebtn_focus_bg; -} - -QPushButton[TitleBtn="true"]:pressed { - background-color: @pushbutton_titlebtn_pressed_bg; -} - -QPushButton[TitleBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[DangerBtn="true"] { - color: @pushbutton_dangerbtn_fg; - border: none; - background-color: @pushbutton_dangerbtn_bg; - min-width: -1; -} - -QPushButton[DangerBtn="true"]:hover { - background-color: @pushbutton_dangerbtn_hover_bg; -} - -QPushButton[DangerBtn="true"]:focus { - background-color: @pushbutton_dangerbtn_focus_bg; -} - -QPushButton[DangerBtn="true"]:pressed { - background-color: @pushbutton_dangerbtn_pressed_bg; -} - -QPushButton[DangerBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[ToolBoxActiveBtn="true"] { - padding: 4px 10px 4px 4px; - margin: 0px; - border: none; - color: @pushbutton_toolboxbtn_active_fg; - background-color: @pushbutton_toolboxbtn_active_bg; - min-width: -1; -} - -QPushButton[ToolBoxActiveBtn="true"]:focus { - background-color: @pushbutton_toolboxbtn_active_focus_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:hover { - background-color: @pushbutton_toolboxbtn_active_hover_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:pressed { - background-color: @pushbutton_toolboxbtn_active_pressed_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -VButtonMenuItem { - padding: 5px; - padding-right: 30px; - border: 1px solid transparent; - background-color: transparent; - min-width: -1; - text-align: left; -} - -VButtonMenuItem[Heading1="true"] { - font-size: 22pt; -} - -VButtonMenuItem[Heading2="true"] { - font-size: 20pt; -} - -VButtonMenuItem[Heading3="true"] { - font-size: 18pt; -} - -VButtonMenuItem[Heading4="true"] { - font-size: 16pt; -} - -VButtonMenuItem[Heading5="true"] { - font-size: 14pt; -} - -VButtonMenuItem[Heading6="true"] { - font-size: 14pt; -} - -VButtonMenuItem:hover { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:focus { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} -/* End QPushButton*/ - -/* QComboBox */ -QComboBox { - padding: 3px; - color: @combobox_fg; - background: @combobox_bg; - border: 1px solid @combobox_border; -} - -QComboBox:focus, QComboBox:on { - background-color: @combobox_focus_bg; - border: 2px solid @combobox_focus_border; -} - -QComboBox::drop-down { - subcontrol-origin: padding; - subcontrol-position: top right; - width: 20px; - border: none; - background: transparent; -} - -QComboBox::down-arrow { - image: url(arrow_dropdown.svg); - width: 20px; - height: 20px; -} - -QComboBox QAbstractItemView { - padding: 2px; - border: 1px solid @combobox_view_border; - background: @combobox_bg; - selection-color: @combobox_view_selected_fg; - selection-background-color: @combobox_view_selected_bg; -} - -QComboBox QAbstractItemView::item { - background: transparent; - padding: 3px; -} - -QComboBox QAbstractItemView::item:hover { - color: @combobox_view_item_hover_fg; - background: @combobox_view_item_hover_bg; -} - -QComboBox#NotebookSelector { - border: none; - border-bottom: 2px solid @combobox_notebookselector_border; - font-size: 13pt; - padding-top: 3px; - padding-bottom: 3px; - icon-size: 30px; - font-weight: bold; - color: @combobox_notebookselector_fg; - background: @combobox_notebookselector_bg; -} - -QComboBox#NotebookSelector::down-arrow { - image: url(arrow_dropdown.svg); - width: 20px; - height: 20px; -} - -QComboBox#NotebookSelector:hover { - color: @combobox_notebookselector_hover_fg; - background: @combobox_notebookselector_hover_bg; -} - -QComboBox#NotebookSelector:focus, QComboBox#NotebookSelector:on { - color: @combobox_notebookselector_focus_fg; - background: @combobox_notebookselector_focus_bg; -} - -QComboBox#NotebookSelector QListWidget { - border: 1px solid @combobox_view_border; - background-color: @combobox_bg; - font-size: 13pt; - font-weight: normal; - icon-size: 30px; -} - -QComboBox#NotebookSelector QListWidget::item { - padding-top: 10px; - padding-bottom: 10px; -} - -QComboBox#NotebookSelector QListWidget::item:hover { - color: @combobox_view_item_hover_fg; - background-color: @combobox_view_item_hover_bg; -} -/* End QComboBox */ - -/* QLabel */ -QLabel { - border: none; - color: @label_fg; - background: transparent; -} - -QLabel[TitleLabel="true"] { - padding-top: 5px; - padding-bottom: 5px; - color: @label_titlelabel_fg; - background-color: @label_titlelabel_bg; -} - -QLabel[ColorRedLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #D32F2F; -} - -QLabel[ColorGreenLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #388E3C; -} - -QLabel[ColorGreyLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #616161; -} - -QLabel[ColorTealLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #00796B; -} - -QLabel[MenuSeparator="true"] { - padding-top: 5px; - padding-bottom: 5px; - margin-top: 3px; - font: italic; - border-top: 1px solid @menu_separator_bg -} - -VVimIndicator QLabel[VimIndicatorKeyLabel="true"] { - font: bold; - color: @vim_indicator_key_label_fg; - background: transparent; -} - -VVimIndicator QLabel[VimIndicatorModeLabel="true"] { - padding: 0px 2px 0px 2px; - font: bold; - color: @vim_indicator_mode_label_fg; - /* background color will be controlled by the code. */ -} - -VTabIndicator QLabel[TabIndicatorLabel="true"] { - color: @tab_indicator_label_fg; - background: transparent; -} -/* End QLabel */ - -/* QLineEdit */ -QLineEdit { - border: 1px solid @lineedit_border; - padding: 3px; - color: @lineedit_fg; - background: @lineedit_bg; - selection-color: @lineedit_selection_fg; - selection-background-color: @lineedit_selection_bg; -} - -QLineEdit:focus { - border: 2px solid @lineedit_focus_border; - background: @lineedit_focus_bg; -} - -QLineEdit[VimCommandLine="true"] { - padding: 0px; - margin: 0px; - border: none; - color: @lineedit_fg; - background: @lineedit_bg; -} -/* End QLineEdit */ - -/* QPlainTextEdit QTextEdit */ -QPlainTextEdit[LineEdit="true"], QTextEdit[LineEdit="true"] { - border: 1px solid @lineedit_border; - padding: 3px; - color: @lineedit_fg; - background: @lineedit_bg; - selection-color: @lineedit_selection_fg; - selection-background-color: @lineedit_selection_bg; -} - -QPlainTextEdit[LineEdit="true"]:focus, QTextEdit[LineEdit="true"]:focus { - border: 2px solid @lineedit_focus_border; - background: @lineedit_focus_bg; -} -/* End QPlainTextEdit QTextEdit */ - -/* QTabWidget */ -QTabWidget { - border: none; -} - -QTabWidget::pane { - border: none; -} -/* End QTabWidget */ - -/* QTabBar */ -QTabBar::tab { - color: @tabbar_fg; - background: @tabbar_bg; - border: none; - border-top: 2px solid transparent; - border-right: 1px solid @tabbar_border; - padding: 2px; -} - -QTabBar::tab:selected { - color: @tabbar_selected_fg; - background: @tabbar_selected_bg; - border-top: 2px solid @master_bg; -} - -QTabBar::tab:hover { - color: @tabbar_hover_fg; - background: @tabbar_hover_bg; -} - -QTabBar::close-button { - image: url(close_grey.svg); -} - -QTabBar::close-button:hover { - image: url(close.svg); -} - -QTabBar::close-button:focus { - image: url(close.svg); -} - -QTabBar::scroller { - width: 20px; -} - -QTabBar QToolButton { - border: none; -} - -QTabBar QToolButton::right-arrow:enabled { - image: url(right.svg); -} - -QTabBar QToolButton::left-arrow:enabled { - image: url(left.svg); -} - -QTabBar QToolButton::right-arrow:disabled { - image: url(right_disabled.svg); -} - -QTabBar QToolButton::left-arrow:disabled { - image: url(left_disabled.svg); -} -/* End QTabBar */ - -VSelectorItemWidget QLabel[SelectorItemShortcutLabel="true"] { - font: bold; - border: 2px solid @selectoritem_border; - padding: 3px; - border-radius: 5px; - background-color: @selectoritem_bg; - color: @selectoritem_fg; -} - -VInsertSelector { - border: none; - background: @insertselector_bg; -} - -/* QTreeView */ -QTreeView { - color: @treeview_fg; - background: @treeview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QTreeView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QTreeView[ItemBorder="true"]::item { - padding-top: 5px; - padding-bottom: 5px; - border-bottom: 1px solid @treeview_item_border_bg; -} - -QTreeView::item:hover { - color: @treeview_item_hover_fg; - background: @treeview_item_hover_bg; -} - -QTreeView::item:selected { - color: @treeview_item_selected_fg; - background: @treeview_item_selected_bg; -} - -QTreeView::item:selected:active { - color: @treeview_item_selected_active_fg; - background: @treeview_item_selected_active_bg; -} - -QTreeView::item:selected:!active { - color: @treeview_item_selected_inactive_fg; - background: @treeview_item_selected_inactive_bg; -} - -QTreeView::branch:has-siblings:!adjoins-item { - border-image: none; -} - -QTreeView::branch:has-siblings:adjoins-item { - border-image: none; -} - -QTreeView::branch:!has-children:!has-siblings:adjoins-item { - border-image: none; -} - -QTreeView::branch:has-children:!has-siblings:closed, -QTreeView::branch:closed:has-children:has-siblings { - border-image: none; - image: url(branch_closed.svg); -} - -QTreeView::branch:open:has-children:!has-siblings, -QTreeView::branch:open:has-children:has-siblings { - border-image: none; - image: url(branch_open.svg); -} - -QTreeView[PlainTree="true"]::branch:has-siblings:!adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:has-siblings:adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:!has-children:!has-siblings:adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:has-children:!has-siblings:closed, -QTreeView[PlainTree="true"]::branch:closed:has-children:has-siblings { - border-image: none; - image: none; -} - -QTreeView[PlainTree="true"]::branch:open:has-children:!has-siblings, -QTreeView[PlainTree="true"]::branch:open:has-children:has-siblings { - border-image: none; - image: none; -} -/* End QTreeView */ - -/* QListView */ -QListView { - color: @listview_fg; - background: @listview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QListView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QListView::item:hover { - color: @listview_item_hover_fg; - background: @listview_item_hover_bg; -} - -QListView::item:selected { - color: @listview_item_selected_fg; - background: @listview_item_selected_bg; -} - -QListView::item:selected:active { - color: @listview_item_selected_active_fg; - background: @listview_item_selected_active_bg; -} - -QListView::item:selected:!active { - color: @listview_item_selected_inactive_fg; - background: @listview_item_selected_inactive_bg; -} -/* End QListView */ - -/* QSplitter */ -QSplitter { - border: none; -} - -QSplitter::handle { - background-color: @splitter_handle_bg; -} - -QSplitter::handle:vertical { - height: 2px; -} - -QSplitter::handle:horizontal { - width: 2px; -} - -QSplitter#MainSplitter { - border: none; -} -/* End QSplitter */ - -/* QStatusBar */ -QStatusBar { - color: @statusbar_fg; - background: @statusbar_bg; - border-top: 1px solid @statusbar_border; -} -/* End QStatusBar */ - -QWidget[MainEditor="true"] { - border: none; -} - -QDialog { - color: @base_fg; - background: @base_bg; -} - -/* QScrollBar */ -QScrollBar::add-page, QScrollBar::sub-page { - background: @scrollbar_page_bg; -} - -QScrollBar:vertical { - background: @scrollbar_bg; - width: 16px; - margin: 16px 0px 16px 0px; - padding: 0px 2px 0px 2px; - border: none; -} - -QScrollBar::handle:vertical { - background: @scrollbar_handle_bg; - min-height: 16px; -} - -QScrollBar::handle:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:vertical { - border: none; - background: @scrollbar_bg; - width: 16px; - height: 16px; - subcontrol-position: bottom; - subcontrol-origin: margin; -} - -QScrollBar::add-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:vertical { - border: none; - background: @scrollbar_bg; - width: 16px; - height: 16px; - subcontrol-position: top; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::down-arrow:vertical { - image: url(down.svg); - width: 16px; - height: 16px; -} - -QScrollBar::up-arrow:vertical { - image: url(up.svg); - width: 16px; - height: 16px; -} - -QScrollBar:horizontal { - background: @scrollbar_bg; - height: 16px; - margin: 0px 16px 0px 16px; - padding: 2px 0px 2px 0px; - border: none; -} - -QScrollBar::handle:horizontal { - background: @scrollbar_handle_bg; - min-width: 16px; -} - -QScrollBar::handle:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:horizontal { - border: none; - background: @scrollbar_bg; - width: 16px; - height: 16px; - subcontrol-position: right; - subcontrol-origin: margin; -} - -QScrollBar::add-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:horizontal { - border: none; - background: @scrollbar_bg; - width: 16px; - height: 16px; - subcontrol-position: left; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::right-arrow:horizontal { - image: url(right.svg); - width: 16px; - height: 16px; -} - -QScrollBar::left-arrow:horizontal { - image: url(left.svg); - width: 16px; - height: 16px; -} -/* End QScrollBar */ - -/* QCheckBox */ -QCheckBox { - spacing: 5px; -} - -QCheckBox::indicator { - width: 20px; - height: 20px; -} - -QCheckBox::indicator:unchecked { - image: url(checkbox_unchecked.svg); -} - -QCheckBox::indicator:unchecked:hover { - background: @checkbox_indicator_hover_bg; -} - -QCheckBox::indicator:unchecked:pressed { - background: @checkbox_indicator_pressed_bg; -} - -QCheckBox::indicator:checked { - image: url(checkbox_checked.svg); -} - -QCheckBox::indicator:checked:hover { - background: @checkbox_indicator_hover_bg; -} - -QCheckBox::indicator:checked:pressed { - background: @checkbox_indicator_pressed_bg; -} - -QCheckBox::indicator:indeterminate:hover { - background: @checkbox_indicator_hover_bg; -} - -QCheckBox::indicator:indeterminate:pressed { - background: @checkbox_indicator_pressed_bg; -} -/* End QCheckBox */ - -/* QRadioButton */ -QRadioButton { - spacing: 5px; -} - -QRadioButton::indicator { - width: 20px; - height: 20px; -} - -QRadioButton::indicator:unchecked { - image: url(radiobutton_unchecked.svg); -} - -QRadioButton::indicator:unchecked:hover { - background: @radiobutton_indicator_hover_bg; -} - -QRadioButton::indicator:unchecked:pressed { - background: @radiobutton_indicator_pressed_bg; -} - -QRadioButton::indicator:checked { - image: url(radiobutton_checked.svg); -} - -QRadioButton::indicator:checked:hover { - background: @radiobutton_indicator_hover_bg; -} - -QRadioButton::indicator:checked:pressed { - background: @radiobutton_indicator_pressed_bg; -} -/* End QRadioButton */ - -/* QSpinBox */ -QSpinBox, QDoubleSpinBox { - border: 1px solid @spinbox_border; - color: @spinbox_fg; - background: @spinbox_bg; - padding-right: 25px; - min-height: 25px; - selection-color: @spinbox_selection_fg; - selection-background-color: @spinbox_selection_bg; -} - -QSpinBox:focus, QDoubleSpinBox::focus { - border: 2px solid @spinbox_focus_border; - background: @spinbox_focus_bg; -} - -QSpinBox::up-button, QDoubleSpinBox::up-button { - subcontrol-origin: border; - subcontrol-position: top right; /* position at the top right corner */ - width: 25px; - border: none; - background: transparent; -} - -QSpinBox::up-button:hover, QDoubleSpinBox::up-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::up-button:pressed, QDoubleSpinBox::up-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::up-arrow, QDoubleSpinBox::up-arrow { - image: url(up.svg); - width: 12px; - height: 12px; -} - -QSpinBox::up-arrow:disabled, QSpinBox::up-arrow:off, QDoubleSpinBox::up-arrow:disabled, QDoubleSpinBox::up-arrow:off { - image: url(up_disabled.svg); -} - -QSpinBox::down-button, QDoubleSpinBox::down-button { - subcontrol-origin: border; - subcontrol-position: bottom right; /* position at the top right corner */ - width: 25px; - border: none; - background: transparent; -} - -QSpinBox::down-button:hover, QDoubleSpinBox::down-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::down-button:pressed, QDoubleSpinBox::down-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::down-arrow, QDoubleSpinBox::down-arrow { - image: url(down.svg); - width: 12px; - height: 12px; -} - -QSpinBox::down-arrow:disabled, QSpinBox::down-arrow:off, QDoubleSpinBox::down-arrow:disabled, QDoubleSpinBox::down-arrow:off { - image: url(down_disabled.svg); -} -/* End QSpinBox */ - -/* QHeaderView */ -QHeaderView::section { - background: @headerview_bg; - color: @headerview_fg; - padding-left: 4px; - border: none; - border-left: 1px solid @headerview_border; - border-bottom: 1px solid @headerview_border; -} - -QHeaderView::section:checked -{ - color: @headerview_checked_fg; - background: @headerview_checked_bg; -} - -/* style the sort indicator */ -QHeaderView::down-arrow { - image: url(down.svg); -} - -QHeaderView::up-arrow { - image: url(up.svg); -} -/* End QHeaderView */ - -QWidget#FindReplaceTitleWidget { - background: @title_bg; -} - -QWidget[ToolBoxTitle="true"] { - border-bottom: 2px solid @toolbox_title_border; -} - -QAbstractScrollArea::corner { - background: @scrollbar_bg; - border: none; -} - -/* QProgressBar */ -QProgressBar { - background: @progressbar_bg; - border: 1px solid @progressbar_border_bg; - text-align: center; -} - -QProgressBar::chunk { - background-color: @progressbar_chunk_bg; - width: 20px; -} -/* End QProgressBar */ diff --git a/src/resources/themes/v_moonlight/v_moonlight_codeblock.css b/src/resources/themes/v_moonlight/v_moonlight_codeblock.css deleted file mode 100644 index 5a604e0b..00000000 --- a/src/resources/themes/v_moonlight/v_moonlight_codeblock.css +++ /dev/null @@ -1,96 +0,0 @@ -/* - -Atom One Dark by Daniel Gamage -Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax - -base: #2c313a -mono-1: #abb2bf -mono-2: #818896 -mono-3: #5c6370 -hue-1: #56b6c2 -hue-2: #61aeee -hue-3: #c678dd -hue-4: #98c379 -hue-5: #e06c75 -hue-5-2: #be5046 -hue-6: #d19a66 -hue-6-2: #e6c07b - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #abb2bf; - background: #2c313a; -} - -.hljs-comment, -.hljs-quote { - color: #5c6370; - font-style: italic; -} - -.hljs-doctag, -.hljs-keyword, -.hljs-formula { - color: #c678dd; -} - -.hljs-section, -.hljs-name, -.hljs-selector-tag, -.hljs-deletion, -.hljs-subst { - color: #e06c75; -} - -.hljs-literal { - color: #56b6c2; -} - -.hljs-string, -.hljs-regexp, -.hljs-addition, -.hljs-attribute, -.hljs-meta-string { - color: #98c379; -} - -.hljs-built_in, -.hljs-class .hljs-title { - color: #e6c07b; -} - -.hljs-attr, -.hljs-variable, -.hljs-template-variable, -.hljs-type, -.hljs-selector-class, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-number { - color: #d19a66; -} - -.hljs-symbol, -.hljs-bullet, -.hljs-link, -.hljs-meta, -.hljs-selector-id, -.hljs-title { - color: #61aeee; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} - -.hljs-link { - text-decoration: underline; -} diff --git a/src/resources/themes/v_pure/arrow_dropdown.svg b/src/resources/themes/v_pure/arrow_dropdown.svg deleted file mode 100644 index 8b465de9..00000000 --- a/src/resources/themes/v_pure/arrow_dropdown.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/src/resources/themes/v_pure/branch_closed.svg b/src/resources/themes/v_pure/branch_closed.svg deleted file mode 100644 index c524ab79..00000000 --- a/src/resources/themes/v_pure/branch_closed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/branch_end.svg b/src/resources/themes/v_pure/branch_end.svg deleted file mode 100644 index baa0c23f..00000000 --- a/src/resources/themes/v_pure/branch_end.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 2 - - - - diff --git a/src/resources/themes/v_pure/branch_more.svg b/src/resources/themes/v_pure/branch_more.svg deleted file mode 100644 index cb0fecad..00000000 --- a/src/resources/themes/v_pure/branch_more.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 2 - - - - diff --git a/src/resources/themes/v_pure/branch_open.svg b/src/resources/themes/v_pure/branch_open.svg deleted file mode 100644 index c1e8e141..00000000 --- a/src/resources/themes/v_pure/branch_open.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/checkbox_checked.svg b/src/resources/themes/v_pure/checkbox_checked.svg deleted file mode 100644 index f017b5b4..00000000 --- a/src/resources/themes/v_pure/checkbox_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_pure/checkbox_unchecked.svg b/src/resources/themes/v_pure/checkbox_unchecked.svg deleted file mode 100644 index 5167523e..00000000 --- a/src/resources/themes/v_pure/checkbox_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_pure/close.svg b/src/resources/themes/v_pure/close.svg deleted file mode 100644 index 26cbf713..00000000 --- a/src/resources/themes/v_pure/close.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_pure/close_grey.svg b/src/resources/themes/v_pure/close_grey.svg deleted file mode 100644 index 24bddd4e..00000000 --- a/src/resources/themes/v_pure/close_grey.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_pure/down.svg b/src/resources/themes/v_pure/down.svg deleted file mode 100644 index 386ac7f8..00000000 --- a/src/resources/themes/v_pure/down.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/down_disabled.svg b/src/resources/themes/v_pure/down_disabled.svg deleted file mode 100644 index 2a53e0f0..00000000 --- a/src/resources/themes/v_pure/down_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/float.svg b/src/resources/themes/v_pure/float.svg deleted file mode 100644 index e4a198f3..00000000 --- a/src/resources/themes/v_pure/float.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/themes/v_pure/left.svg b/src/resources/themes/v_pure/left.svg deleted file mode 100644 index aee69f4a..00000000 --- a/src/resources/themes/v_pure/left.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/left_disabled.svg b/src/resources/themes/v_pure/left_disabled.svg deleted file mode 100644 index 3cabd4b5..00000000 --- a/src/resources/themes/v_pure/left_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/line.svg b/src/resources/themes/v_pure/line.svg deleted file mode 100644 index 8c981419..00000000 --- a/src/resources/themes/v_pure/line.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 2 - - - diff --git a/src/resources/themes/v_pure/menu_checkbox.svg b/src/resources/themes/v_pure/menu_checkbox.svg deleted file mode 100644 index 0aeb35a1..00000000 --- a/src/resources/themes/v_pure/menu_checkbox.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_pure/menu_radiobutton.svg b/src/resources/themes/v_pure/menu_radiobutton.svg deleted file mode 100644 index aafaa309..00000000 --- a/src/resources/themes/v_pure/menu_radiobutton.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_pure/radiobutton_checked.svg b/src/resources/themes/v_pure/radiobutton_checked.svg deleted file mode 100644 index c9834cc5..00000000 --- a/src/resources/themes/v_pure/radiobutton_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_pure/radiobutton_unchecked.svg b/src/resources/themes/v_pure/radiobutton_unchecked.svg deleted file mode 100644 index 7cd0863a..00000000 --- a/src/resources/themes/v_pure/radiobutton_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_pure/right.svg b/src/resources/themes/v_pure/right.svg deleted file mode 100644 index c524ab79..00000000 --- a/src/resources/themes/v_pure/right.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/right_disabled.svg b/src/resources/themes/v_pure/right_disabled.svg deleted file mode 100644 index c0c83ba8..00000000 --- a/src/resources/themes/v_pure/right_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/up.svg b/src/resources/themes/v_pure/up.svg deleted file mode 100644 index 52be26da..00000000 --- a/src/resources/themes/v_pure/up.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/up_disabled.svg b/src/resources/themes/v_pure/up_disabled.svg deleted file mode 100644 index 36e54158..00000000 --- a/src/resources/themes/v_pure/up_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/v_pure.css b/src/resources/themes/v_pure/v_pure.css deleted file mode 100644 index 336862e2..00000000 --- a/src/resources/themes/v_pure/v_pure.css +++ /dev/null @@ -1,297 +0,0 @@ -body { - margin: 0 auto; - font-family: Helvetica, sans-serif, Tahoma, Arial, Verdana, Geneva, Georgia, Palatino, "Times New Roman", "Hiragino Sans GB", "冬青黑体", "Microsoft YaHei", "微软雅黑", "Microsoft YaHei UI", "WenQuanYi Micro Hei", "文泉驿雅黑", Dengxian, "等线体", STXihei, "华文细黑", "Liberation Sans", "Droid Sans", NSimSun, "新宋体", SimSun, "宋体"; - color: #363636; - line-height: 1; - padding: 30px; - background: #F5F5F5; -} - -h1, h2, h3, h4, h5, h6 { - color: #363636; - font-weight: bold; - margin-bottom: 24px; - padding: 0; -} - -p { - padding: 0; -} - -h1 { - font-size: 36px; -} - -h2 { - font-size: 30px; -} - -h3 { - font-size: 26px; -} - -h4 { - font-size: 22px; -} - -h5 { - font-size: 20px; -} - -h6 { - font-size: 18px; -} - -a { - color: #0099ff; - margin: 0; - padding: 0; - vertical-align: baseline; -} - -a:hover { - text-decoration: none; - color: #ff6600; -} - -a:visited { - color: purple; -} - -ul, ol { - padding: 0; - padding-left: 24px; -} - -li { - line-height: 24px; -} - -li ul, li ul { - margin-left: 24px; -} - -p, ul, ol { - font-size: 16px; - line-height: 24px; -} - -pre { - display: block; - overflow-y: hidden; - overflow-x: auto; -} - -code { - font-family: Consolas, Monaco, Andale Mono, Monospace, Courier New; - line-height: 1.5; - font-size: 14px; - color: #4527A0; -} - -pre code { - margin: 0; - padding: 0; - border: none; - color: #363636; -} - -aside { - display: block; - float: right; - width: 390px; -} - -blockquote { - color: #666; - border-left:.5em solid #7a7a7a; - padding: 0 2em; - margin-left:0; -} - -blockquote p { - color: #666; -} - -hr { - display: block; - text-align: left; - margin: 1em 0; - border: none; - height: 2px; - background: #999; -} - -table { - padding: 0; - border-collapse: collapse; -} - -table tr { - border-top: 1px solid #cccccc; - background-color: white; - margin: 0; - padding: 0; -} - -table tr:nth-child(2n) { - background-color: #f8f8f8; -} - -table tr th { - font-weight: bold; - border: 1px solid #cccccc; - margin: 0; - padding: 6px 13px; -} - -table tr td { - border: 1px solid #cccccc; - margin: 0; - padding: 6px 13px; -} - -table tr th :first-child, table tr td :first-child { - margin-top: 0; -} - -table tr th :last-child, table tr td :last-child { - margin-bottom: 0; -} - -div.mermaid-diagram { - overflow-y: hidden; -} - -pre.mermaid-diagram { - overflow-y: hidden; -} - -div.flowchart-diagram { - overflow-y: hidden; -} - -pre.flowchart-diagram { - overflow-y: hidden; -} - -.img-package { - text-align: center; -} - -img.img-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -div.img-caption { - min-width: 20%; - max-width: 80%; - display: inline-block; - padding: 10px; - margin: 0 auto; - border-bottom: 1px solid #c0c0c0; - color: #6c6c6c; - text-align: center; - line-height: 1.5; -} - -/* For Highlight.js Line Number */ -table.hljs-ln tr { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td.hljs-ln-numbers { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - - text-align: center; - color: #AAA; - border-right: 1px solid #CCC; - vertical-align: top; - padding-right: 5px; -} - -table.hljs-ln tr td.hljs-ln-code { - padding-left: 10px; -} - -::-webkit-scrollbar { - background-color: #EAEAEA; - width: 14px; - height: 14px; - border: none; -} - -::-webkit-scrollbar-corner { - background-color: #EAEAEA; -} - -::-webkit-scrollbar-button { - /* This selector affects the styling of both the up & down and left & right buttons of a scrollbar */ - height: 14px; - width: 14px; - background-color: #EAEAEA; -} - -::-webkit-scrollbar-button:hover { - background-color: #D0D0D0; -} - -::-webkit-scrollbar-button:active { - background-color: #B2B2B2; -} - -::-webkit-scrollbar-track { - /* This selector affects the styling of the area in the scrollbar between the two buttons */ - background-color: #EAEAEA; -} - -::-webkit-scrollbar-thumb { - /* This selector affects the styling of draggable element of the scollbar */ - border: none; - background-color: #DADADA; -} - -::-webkit-scrollbar-thumb:hover { - background-color: #D0D0D0; -} - -::-webkit-scrollbar-thumb:active { - background-color: #B2B2B2; -} - -::-webkit-scrollbar-button:horizontal:increment { - background-image: url(right.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:horizontal:decrement { - background-image: url(left.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:vertical:increment { - background-image: url(down.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:vertical:decrement { - background-image: url(up.svg); - background-repeat: no-repeat; - background-size: contain; -} diff --git a/src/resources/themes/v_pure/v_pure.mdhl b/src/resources/themes/v_pure/v_pure.mdhl deleted file mode 100644 index a434d389..00000000 --- a/src/resources/themes/v_pure/v_pure.mdhl +++ /dev/null @@ -1,168 +0,0 @@ -# This is the default markdown styles used for Peg-Markdown-Highlight -# created by Le Tan(tamlokveer@gmail.com). -# For a complete description of the syntax, please refer to the original -# documentation of the style parser -# [The Syntax of PEG Markdown Highlight Stylesheets](http://hasseg.org/peg-markdown-highlight/docs/stylesheet_syntax.html). -# VNote adds some styles in the syntax which will be marked [VNote] in the comment. -# -# Note: Empty lines within a section is NOT allowed. -# Note: Do NOT modify this file directly. Copy it and tune your own style! - -editor -# QTextEdit just choose the first available font, so specify the Chinese fonts first -# Do not use "" to quote the name -font-family: Hiragino Sans GB, 冬青黑体, Microsoft YaHei, 微软雅黑, Microsoft YaHei UI, WenQuanYi Micro Hei, 文泉驿雅黑, Dengxian, 等线体, STXihei, 华文细黑, Liberation Sans, Droid Sans, NSimSun, 新宋体, SimSun, 宋体, Helvetica, sans-serif, Tahoma, Arial, Verdana, Geneva, Georgia, Times New Roman -font-size: 12 -foreground: 222222 -background: f5f5f5 -# [VNote] Style for trailing space -trailing-space: a8a8a8 -# [VNote] Style for line number -line-number-background: eaeaea -line-number-foreground: 424242 -# [VNote] Style for selected word highlight -selected-word-background: dfdf00 -# [VNote] Style for searched word highlight -searched-word-background: 4db6ac -# [VNote] Style for searched word under cursor highlight -searched-word-cursor-background: 66bb6a -# [VNote] Style for incremental searched word highlight -incremental-searched-word-background: ce93d8 -# [VNote] Style for color column in fenced code block -color-column-background: dd0000 -color-column-foreground: ffff00 -# [VNote} Style for preview image line -preview-image-line-foreground: 9575cd - -editor-selection -foreground: eeeeee -background: 005fff - -editor-current-line -background: c5cae9 -# [VNote] Vim insert mode cursor line background -vim-insert-background: c5cae9 -# [VNote] Vim normal mode cursor line background -vim-normal-background: c6c6c6 -# [VNote] Vim visual mode cursor line background -vim-visual-background: 90caf9 -# [VNote] Vim replace mode cursor line background -vim-replace-background: f8bbd0 - -H1 -foreground: 222222 -font-style: bold -font-size: +8 - -H2 -foreground: 222222 -font-style: bold -font-size: +6 - -H3 -foreground: 222222 -font-style: bold -font-size: +4 - -H4 -foreground: 222222 -font-style: bold -font-size: +2 - -H5 -foreground: 222222 -font-style: bold -font-size: +2 - -H6 -foreground: 222222 -font-style: bold -font-size: +2 - -HRULE -foreground: 586e75 - -LIST_BULLET -foreground: d33682 -font-style: bold -font-size: +2 - -LIST_ENUMERATOR -foreground: 0000ff - -LINK -foreground: 005fff - -AUTO_LINK_URL -foreground: 005fff - -AUTO_LINK_EMAIL -foreground: 005fff - -IMAGE -foreground: 616161 - -REFERENCE -foreground: b58900 - -CODE -foreground: 551a8b -font-family: Consolas, Monaco, Andale Mono, Monospace, Courier New - -EMPH -font-style: italic - -STRONG -font-style: bold - -HTML_ENTITY -foreground: 6c71c4 - -COMMENT -foreground: 93a1a1 - -VERBATIM -foreground: 551a8b -font-family: Consolas, Monaco, Andale Mono, Monospace, Courier New -# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, color) -# The last occurence of the same attribute takes effect -# Could specify multiple attribute in one line -hljs-comment: 6c6c6c -hljs-keyword: 0000ee -hljs-attribute: 0000ee -hljs-selector-tag: 0000ee -hljs-meta-keyword: 0000ee -hljs-doctag: 0000ee -hljs-name: 0000ee -hljs-type: 880000 -hljs-string: 880000 -hljs-number: 880000 -hljs-selector-id: 880000 -hljs-selector-class: 880000 -hljs-quote: 880000 -hljs-template-tag: 880000 -hljs-deletion: 880000 -hljs-title: bold, 880000 -hljs-section: bold, 880000 -hljs-regexp: bc6060 -hljs-symbol: bc6060 -hljs-variable: bc6060 -hljs-template-variable: bc6060 -hljs-link: bc6060 -hljs-selector-attr: bc6060 -hljs-selector-pseudo: bc6060 -hljs-literal: af00d7 -hljs-built_in: 008700 -hljs-bullet: 008700 -hljs-code: 008700 -hljs-addition: 008700 -hljs-meta: 1f7199 -hljs-meta-string: 4d99bf -hljs-emphasis: italic -hljs-strong: bold - -BLOCKQUOTE -foreground: 00af00 - -STRIKE -strike-color: 586e75 diff --git a/src/resources/themes/v_pure/v_pure.palette b/src/resources/themes/v_pure/v_pure.palette deleted file mode 100644 index 497a8c55..00000000 --- a/src/resources/themes/v_pure/v_pure.palette +++ /dev/null @@ -1,341 +0,0 @@ -; File path could be absolute path or relative path (related to this file). -; Use @color_tag to reference a style. - -[metadata] -qss_file=v_pure.qss -mdhl_file=v_pure.mdhl -css_file=v_pure.css -codeblock_css_file=v_pure_codeblock.css - -[phony] -; Abstract color attributes. -master_fg=#F5F5F5 -master_bg=#00897B -master_light_bg=#80CBC4 -master_focus_bg=#009688 -master_hover_bg=#009688 -master_pressed_bg=#00796B - -base_fg=#222222 -base_bg=#EAEAEA - -main_fg=@base_fg -main_bg=#base_bg - -title_fg=@base_fg -title_bg=@base_bg - -disabled_fg=#9E9E9E - -content_fg=@base_fg -content_bg=@base_bg - -border_bg=#D3D3D3 - -separator_bg=#D3D3D3 - -hover_fg=@base_fg -hover_bg=#D0D0D0 - -selected_fg=@base_fg -selected_bg=#BDBDBD - -active_fg=@selected_fg -active_bg=@selected_bg - -inactive_fg=@selected_fg -inactive_bg=#D3D3D3 - -focus_fg=@selected_fg -focus_bg=@selected_bg - -pressed_fg=@base_fg -pressed_bg=#B2B2B2 - -edit_fg=#222222 -edit_bg=#F5F5F5 -edit_focus_bg=#E0F2F1 -edit_focus_border=@master_bg -edit_selection_fg=@edit_fg -edit_selection_bg=@master_light_bg - -icon_fg=#222222 -icon_disabled_fg=@disabled_fg - -danger_fg=#F5F5F5 -danger_bg=#C9302C -danger_focus_bg=#D9534F -danger_hover_bg=#D9534F -danger_pressed_bg=#AC2925 - -[soft_defined] -; VAvatar. -avatar_border_bg=@selected_bg -avatar_fg=@base_bg -avatar_bg=@base_fg -; The border background color of the avatar when Captain mode is triggered. -avatar_captain_mode_border_bg=@master_bg - -; Style of the label in Navigation mode. -navigation_label_fg=@master_fg -navigation_label_bg=@master_bg - -; Style of the bubble of VButtonWithWidget. -bubble_fg=@master_fg -bubble_bg=@master_bg - -; Icons' foreground. -danger_icon_fg=@danger_bg -item_icon_fg=@icon_fg -title_icon_fg=@icon_fg - -; VVimIndicator. -vim_indicator_key_label_fg=@base_fg -vim_indicator_mode_label_fg=@base_fg -vim_indicator_cmd_edit_pending_bg=@selected_bg - -; VTabIndicator. -tab_indicator_label_fg=@base_fg - -; Html template. -template_title_flash_light_fg=@master_light_bg -template_title_flash_dark_fg=@master_bg - -[widgets] -; Widget color attributes. - -; QWidget. -widget_fg=@base_fg - -; Separator of dock widgets. -dock_separator_bg=@border_bg -dock_separator_hover_bg=@border_bg - -; Menubar. -menubar_bg=@main_bg -menubar_fg=@main_fg -menubar_item_selected_bg=@selected_bg - -; Menu. -menu_bg=@base_bg -menu_fg=@base_fg -menu_item_disabled_fg=@disabled_fg -menu_item_selected_fg=@selected_fg -menu_item_selected_bg=@selected_bg -menu_separator_bg=@separator_bg -menu_icon_fg=@icon_fg -menu_icon_danger_fg=@danger_icon_fg - -; Tooltip. -tooltip_bg=@master_bg -tooltip_fg=@master_fg - -; Toolbar. -toolbar_bg=@main_bg -toolbar_separator_bg=@separator_bg -toolbutton_hover_bg=@hover_bg -toolbutton_pressed_bg=@pressed_bg -toolbutton_checked_bg=@selected_bg -toolbutton_icon_fg=@icon_fg -toolbutton_icon_danger_fg=@danger_icon_fg - -; Toolbox. -toolbox_icon_fg=@master_bg -toolbox_icon_active_fg=@master_fg -toolbox_title_border=@master_bg - -; Dockwidget. -dockwidget_title_fg=@title_fg -dockwidget_title_bg=@title_bg -dockwidget_button_hover_bg=@hover_bg - -; PushButton. -pushbutton_fg=@base_fg -pushbutton_bg=transparent -pushbutton_border=@border_bg -pushbutton_pressed_bg=@pressed_bg -pushbutton_focus_bg=@focus_bg -pushbutton_checked_bg=@selected_bg -pushbutton_hover_bg=@hover_bg -pushbutton_default_border=@master_bg -pushbutton_disabled_fg=@disabled_fg -pushbutton_disabled_bg=@pushbutton_bg - -pushbutton_specialbtn_fg=@master_fg -pushbutton_specialbtn_bg=@master_bg -pushbutton_specialbtn_focus_bg=@master_focus_bg -pushbutton_specialbtn_hover_bg=@master_hover_bg -pushbutton_specialbtn_checked_bg=#3F51B5 -pushbutton_specialbtn_pressed_bg=@master_pressed_bg - -pushbutton_cornerbtn_hover_bg=@hover_bg -pushbutton_cornerbtn_focus_bg=@focus_bg -pushbutton_cornerbtn_pressed_bg=@pressed_bg - -pushbutton_statusbtn_hover_bg=@hover_bg -pushbutton_statusbtn_focus_bg=@focus_bg -pushbutton_statusbtn_pressed_bg=@pressed_bg - -pushbutton_flatbtn_hover_bg=@hover_bg -pushbutton_flatbtn_focus_bg=@focus_bg -pushbutton_flatbtn_pressed_bg=@pressed_bg - -pushbutton_selectionbtn_hover_bg=@hover_bg -pushbutton_selectionbtn_focus_bg=@focus_bg -pushbutton_selectionbtn_pressed_bg=@pressed_bg - -pushbutton_titlebtn_bg=@title_bg -pushbutton_titlebtn_hover_bg=@hover_bg -pushbutton_titlebtn_focus_bg=@focus_bg -pushbutton_titlebtn_pressed_bg=@pressed_bg - -pushbutton_dangerbtn_fg=@danger_fg -pushbutton_dangerbtn_bg=@danger_bg -pushbutton_dangerbtn_hover_bg=@danger_hover_bg -pushbutton_dangerbtn_focus_bg=@danger_focus_bg -pushbutton_dangerbtn_pressed_bg=@danger_pressed_bg - -pushbutton_toolboxbtn_active_fg=@master_fg -pushbutton_toolboxbtn_active_bg=@master_bg -pushbutton_toolboxbtn_active_focus_bg=@master_focus_bg -pushbutton_toolboxbtn_active_hover_bg=@master_hover_bg -pushbutton_toolboxbtn_active_pressed_bg=@master_pressed_bg - -button_icon_fg=@icon_fg -button_icon_danger_fg=@danger_icon_fg - -; ComboBox. -combobox_border=@border_bg -combobox_fg=@content_fg -combobox_bg=@content_bg -combobox_view_border=@border_bg -combobox_view_selected_bg=@selected_bg -combobox_view_selected_fg=@selected_fg -combobox_view_item_hover_fg=@hover_fg -combobox_view_item_hover_bg=@hover_bg -combobox_focus_bg=@edit_focus_bg -combobox_focus_border=@edit_focus_border -combobox_item_icon_fg=@item_icon_fg - -combobox_notebookselector_fg=@master_pressed_bg -combobox_notebookselector_bg=@combobox_bg -combobox_notebookselector_border=@master_bg -combobox_notebookselector_hover_fg=@master_bg -combobox_notebookselector_hover_bg=@hover_bg -combobox_notebookselector_focus_fg=@master_bg -combobox_notebookselector_focus_bg=@focus_bg - -; Label. -label_fg=@base_fg -label_titlelabel_fg=@title_fg -label_titlelabel_bg=@title_bg - -; LineEdit. -lineedit_border=@border_bg -lineedit_fg=@edit_fg -lineedit_bg=@edit_bg -lineedit_focus_bg=@edit_focus_bg -lineedit_focus_border=@edit_focus_border -lineedit_selection_fg=@edit_selection_fg -lineedit_selection_bg=@edit_selection_bg - -; TabWidget. -tabwidget_pane_border=@selected_bg - -; TabBar. -tabbar_fg=@base_fg -tabbar_bg=@base_bg -tabbar_border=@border_bg - -tabbar_selected_fg=@edit_fg -tabbar_selected_bg=@edit_bg -tabbar_selected_border=@border_bg - -tabbar_hover_fg=@hover_fg -tabbar_hover_bg=@hover_bg - -tabbar_icon_fg=@icon_fg -tabbar_icon_special_fg=@danger_bg - -; SelectorItem. -selectoritem_border=@master_bg -selectoritem_fg=@base_fg -selectoritem_bg=@base_bg - -; InsertSelector. -insertselector_bg=@base_bg - -; TreeView. -treeview_fg=@content_fg -treeview_bg=@content_bg -treeview_item_border_bg=@border_bg -treeview_item_hover_fg=@hover_fg -treeview_item_hover_bg=@hover_bg -treeview_item_selected_fg=@selected_fg -treeview_item_selected_bg=@selected_bg -treeview_item_selected_avtive_fg=@active_fg -treeview_item_selected_avtive_bg=@active_bg -treeview_item_selected_inactive_fg=@inactive_fg -treeview_item_selected_inactive_bg=@inactive_bg -treeview_item_icon_fg=@item_icon_fg - -; ListView. -listview_fg=@content_fg -listview_bg=@content_bg -listview_item_hover_fg=@hover_fg -listview_item_hover_bg=@hover_bg -listview_item_selected_fg=@selected_fg -listview_item_selected_bg=@selected_bg -listview_item_selected_avtive_fg=@active_fg -listview_item_selected_avtive_bg=@active_bg -listview_item_selected_inactive_fg=@inactive_fg -listview_item_selected_inactive_bg=@inactive_bg - -; Splitter. -splitter_handle_bg=@border_bg - -; StatusBar. -statusbar_fg=@main_fg -statusbar_bg=@main_bg - -; ScrollBar. -scrollbar_bg=@base_bg -scrollbar_page_bg=transparent -scrollbar_handle_bg=#DADADA -scrollbar_handle_hover_bg=@hover_bg -scrollbar_handle_pressed_bg=@pressed_bg - -; VEditWindow. -editwindow_corner_icon_fg=@master_bg -editwindow_corner_icon_inactive_fg=#D3D3D3 - -; CheckBox. -checkbox_indicator_hover_bg=@hover_bg -checkbox_indicator_pressed_bg=@pressed_bg - -; RadioButton. -radiobutton_indicator_hover_bg=@hover_bg -radiobutton_indicator_pressed_bg=@pressed_bg - -; SpinBox. -spinbox_fg=@edit_fg -spinbox_bg=@edit_bg -spinbox_border=@border_bg -spinbox_selection_fg=@edit_selection_fg -spinbox_selection_bg=@edit_selection_bg -spinbox_focus_border=@edit_focus_border -spinbox_focus_bg=@edit_focus_bg -spinbox_button_hover_bg=@hover_bg -spinbox_button_pressed_bg=@pressed_bg - -; HeaderView. -headerview_bg=#E0E0E0 -headerview_fg=@base_fg -headerview_border=@border_bg -headerview_checked_fg=@selected_fg -headerview_checked_bg=@selected_bg - -; ProgressBar. -progressbar_bg=@edit_bg -progressbar_border_bg=@border_bg -progressbar_chunk_bg=@master_light_bg diff --git a/src/resources/themes/v_pure/v_pure.qss b/src/resources/themes/v_pure/v_pure.qss deleted file mode 100644 index c42f8b35..00000000 --- a/src/resources/themes/v_pure/v_pure.qss +++ /dev/null @@ -1,1287 +0,0 @@ -QToolTip -{ - border: none; - background: @tooltip_bg; - color: @tooltip_fg; -} - -/* QWidget */ -QWidget -{ - color: @widget_fg; - font-family: "Hiragino Sans GB", "冬青黑体", "Microsoft YaHei", "微软雅黑", "Microsoft YaHei UI", "WenQuanYi Micro Hei", "文泉驿雅黑", "Dengxian", "等线体", "STXihei", "华文细黑", "Liberation Sans", "Droid Sans", "NSimSun", "新宋体", "SimSun", "宋体", "Helvetica", "sans-serif", "Tahoma", "Arial", "Verdana", "Geneva", "Georgia", "Times New Roman"; -} - -QWidget[NotebookPanel="true"] { - padding-left: 3px; -} - -/* End QWidget */ - -/* QMainWindow */ -QMainWindow { - color: @base_fg; - background: @base_bg; -} - -QMainWindow::separator { - background: @dock_separator_bg; - width: 2px; - height: 2px; -} - -QMainWindow::separator:hover { - background: @dock_separator_hover_bg; -} -/* End QMainWindow */ - -QMenuBar { - border: none; - background: @menubar_bg; - color: @menubar_fg; -} - -QMenuBar::item:selected { - background: @menubar_item_selected_bg; -} - -/* QMenu */ -QMenu { - background: @menu_bg; - color: @menu_fg; - margin: 2px; -} - -QMenu::icon { - margin: 5px; -} - -QMenu::item { - padding: 5px 30px 5px 30px; - border: 1px solid transparent; -} - -QMenu::item:disabled { - color: @menu_item_disabled_fg; -} - -QMenu::item:selected { - color: @menu_item_selected_fg; - background: @menu_item_selected_bg; -} - -QMenu::icon:checked { /* appearance of a 'checked' icon */ - border: 2px solid @menu_fg; -} - -QMenu::separator { - height: 2px; - background: @menu_separator_bg; - margin-left: 10px; - margin-right: 5px; -} - -QMenu::indicator { - width: 20px; - height: 20px; -} - -QMenu::indicator:non-exclusive:unchecked { - image: none; -} - -QMenu::indicator:non-exclusive:checked { - image: url(menu_checkbox.svg); -} - -QMenu::indicator:exclusive:unchecked { - image: none; -} - -QMenu::indicator:exclusive:checked { - image: url(menu_radiobutton.svg); -} -/* End QMenu */ - -QToolBar { - border: none; - background: @toolbar_bg; -} - -QToolBar::separator { - width: 1px; - height: 1px; - border: none; - background: @toolbar_separator_bg; -} - -/* QToolButton */ -QToolButton { - border: none; - background: transparent; - margin: 1px 3px 1px 3px; - padding: 0px; -} - -QToolButton[popupMode="1"] { /* only for MenuButtonPopup */ - padding-right: 16px; /* make way for the popup button */ -} - -QToolButton[popupMode="2"] { /* only for InstantPopup */ - padding-right: 10px; /* make way for the popup button */ -} - -QToolButton:hover { - border:none; - background: @toolbutton_hover_bg; -} - -QToolButton:pressed { - background: @toolbutton_pressed_bg; -} - -QToolButton:checked { - background: @toolbutton_checked_bg; -} - -QToolButton:checked:hover { - background: @toolbutton_hover_bg; -} - -/* the subcontrols below are used only in the MenuButtonPopup mode */ -QToolButton::menu-button { - border: none; - width: 16px; -} - -QToolButton::menu-arrow { - image: url(arrow_dropdown.svg); - width: 16px; - height: 16px; -} -/* End QToolButton*/ - -/* DockWidget */ -QDockWidget { - color: @dockwidget_title_fg; - titlebar-close-icon: url(close.svg); - titlebar-normal-icon: url(float.svg); -} - -QDockWidget::Title { - background: @dockwidget_title_bg; - text-align: center left; -} - -QDockWidget::close-button, QDockWidget::float-button { - border: none; -} - -QDockWidget::close-button:hover, QDockWidget::float-button:hover { - background: @dockwidget_button_hover_bg; -} -/* End DockWidget */ - -/* QPushButton */ -QPushButton { - color: @pushbutton_fg; - background: @pushbutton_bg; - border: 1px solid @pushbutton_border; - padding: 3px; - min-width: 80px; -} - -QPushButton:focus { - background-color: @pushbutton_focus_bg; -} - -QPushButton:pressed { - background-color: @pushbutton_pressed_bg; -} - -QPushButton:checked { - background-color: @pushbutton_checked_bg; -} - -QPushButton:checked:hover { - background-color: @pushbutton_hover_bg; -} - -QPushButton:hover { - background-color: @pushbutton_hover_bg; -} - -QPushButton:flat { - border: none; -} - -QPushButton:default { - border-color: @pushbutton_default_border; -} - -QPushButton:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton::menu-indicator { - image: url(arrow_dropdown.svg); - width: 16px; - height: 16px; -} - -QPushButton[SpecialBtn="true"] { - color: @pushbutton_specialbtn_fg; - background: @pushbutton_specialbtn_bg; -} - -QPushButton[SpecialBtn="true"]:focus { - background-color: @pushbutton_specialbtn_focus_bg; -} - -QPushButton[SpecialBtn="true"]:pressed { - background-color: @pushbutton_specialbtn_pressed_bg; -} - -QPushButton[SpecialBtn="true"]:checked { - background-color: @pushbutton_specialbtn_checked_bg; -} - -QPushButton[SpecialBtn="true"]:checked:hover { - background-color: @pushbutton_specialbtn_hover_bg; -} - -QPushButton[SpecialBtn="true"]:hover { - background-color: @pushbutton_specialbtn_hover_bg; -} - -QPushButton[SpecialBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[CornerBtn="true"] { - padding: 4px -2px 4px -2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[CornerBtn="true"]::menu-indicator { - image: none; -} - -QPushButton[CornerBtn="true"]:hover { - background-color: @pushbutton_cornerbtn_hover_bg; -} - -QPushButton[CornerBtn="true"]:focus { - background-color: @pushbutton_cornerbtn_focus_bg; -} - -QPushButton[CornerBtn="true"]:pressed { - background-color: @pushbutton_cornerbtn_pressed_bg; -} - -QPushButton[CornerBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[StatusBtn="true"] { - font: bold; - padding: 0px 2px 0px 2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[StatusBtn="true"]:hover { - background-color: @pushbutton_statusbtn_hover_bg; -} - -QPushButton[StatusBtn="true"]:focus { - background-color: @pushbutton_statusbtn_focus_bg;; -} - -QPushButton[StatusBtn="true"]:pressed { - background-color: @pushbutton_statusbtn_pressed_bg; -} - -QPushButton[StatusBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[FlatBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[FlatBtn="true"]:hover { - background-color: @pushbutton_flatbtn_hover_bg; -} - -QPushButton[FlatBtn="true"]:focus { - background-color: @pushbutton_flatbtn_focus_bg; -} - -QPushButton[FlatBtn="true"]:pressed { - background-color: @pushbutton_flatbtn_pressed_bg; -} - -QPushButton[FlatBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[SelectionBtn="true"] { - padding: 4px 10px 4px 10px; - border: none; - background-color: transparent; - font-size: 15pt; - text-align: left; - min-width: -1; -} - -QPushButton[SelectionBtn="true"]:hover { - background-color: @pushbutton_selectionbtn_hover_bg; -} - -QPushButton[SelectionBtn="true"]:focus { - background-color: @pushbutton_selectionbtn_focus_bg; -} - -QPushButton[SelectionBtn="true"]:pressed { - background-color: @pushbutton_selectionbtn_pressed_bg; -} - -QPushButton[SelectionBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[TitleBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: @pushbutton_titlebtn_bg; - min-width: -1; -} - -QPushButton[TitleBtn="true"]:hover { - background-color: @pushbutton_titlebtn_hover_bg; -} - -QPushButton[TitleBtn="true"]:focus { - background-color: @pushbutton_titlebtn_focus_bg; -} - -QPushButton[TitleBtn="true"]:pressed { - background-color: @pushbutton_titlebtn_pressed_bg; -} - -QPushButton[TitleBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[DangerBtn="true"] { - color: @pushbutton_dangerbtn_fg; - border: none; - background-color: @pushbutton_dangerbtn_bg; - min-width: -1; -} - -QPushButton[DangerBtn="true"]:hover { - background-color: @pushbutton_dangerbtn_hover_bg; -} - -QPushButton[DangerBtn="true"]:focus { - background-color: @pushbutton_dangerbtn_focus_bg; -} - -QPushButton[DangerBtn="true"]:pressed { - background-color: @pushbutton_dangerbtn_pressed_bg; -} - -QPushButton[DangerBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[ToolBoxActiveBtn="true"] { - padding: 4px 10px 4px 4px; - margin: 0px; - border: none; - color: @pushbutton_toolboxbtn_active_fg; - background-color: @pushbutton_toolboxbtn_active_bg; - min-width: -1; -} - -QPushButton[ToolBoxActiveBtn="true"]:focus { - background-color: @pushbutton_toolboxbtn_active_focus_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:hover { - background-color: @pushbutton_toolboxbtn_active_hover_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:pressed { - background-color: @pushbutton_toolboxbtn_active_pressed_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -VButtonMenuItem { - padding: 5px; - padding-right: 30px; - border: 1px solid transparent; - background-color: transparent; - min-width: -1; - text-align: left; -} - -VButtonMenuItem[Heading1="true"] { - font-size: 22pt; -} - -VButtonMenuItem[Heading2="true"] { - font-size: 20pt; -} - -VButtonMenuItem[Heading3="true"] { - font-size: 18pt; -} - -VButtonMenuItem[Heading4="true"] { - font-size: 16pt; -} - -VButtonMenuItem[Heading5="true"] { - font-size: 14pt; -} - -VButtonMenuItem[Heading6="true"] { - font-size: 14pt; -} - -VButtonMenuItem:hover { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:focus { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} -/* End QPushButton*/ - -/* QComboBox */ -QComboBox { - padding: 3px; - color: @combobox_fg; - background: @combobox_bg; - border: 1px solid @combobox_border; -} - -QComboBox:focus, QComboBox:on { - background-color: @combobox_focus_bg; - border: 2px solid @combobox_focus_border; -} - -QComboBox::drop-down { - subcontrol-origin: padding; - subcontrol-position: top right; - width: 20px; - border: none; - background: transparent; -} - -QComboBox::down-arrow { - image: url(arrow_dropdown.svg); - width: 20px; - height: 20px; -} - -QComboBox QAbstractItemView { - padding: 2px; - border: 1px solid @combobox_view_border; - background: @combobox_bg; - selection-color: @combobox_view_selected_fg; - selection-background-color: @combobox_view_selected_bg; -} - -QComboBox QAbstractItemView::item { - background: transparent; - padding: 3px; -} - -QComboBox QAbstractItemView::item:hover { - color: @combobox_view_item_hover_fg; - background: @combobox_view_item_hover_bg; -} - -QComboBox#NotebookSelector { - border: none; - border-bottom: 2px solid @combobox_notebookselector_border; - font-size: 13pt; - padding-top: 3px; - padding-bottom: 3px; - icon-size: 30px; - font-weight: bold; - color: @combobox_notebookselector_fg; - background: @combobox_notebookselector_bg; -} - -QComboBox#NotebookSelector::down-arrow { - image: url(arrow_dropdown.svg); - width: 20px; - height: 20px; -} - -QComboBox#NotebookSelector:hover { - color: @combobox_notebookselector_hover_fg; - background: @combobox_notebookselector_hover_bg; -} - -QComboBox#NotebookSelector:focus, QComboBox#NotebookSelector:on { - color: @combobox_notebookselector_focus_fg; - background: @combobox_notebookselector_focus_bg; -} - -QComboBox#NotebookSelector QListWidget { - border: 1px solid @combobox_view_border; - background-color: @combobox_bg; - font-size: 13pt; - font-weight: normal; - icon-size: 30px; -} - -QComboBox#NotebookSelector QListWidget::item { - padding-top: 10px; - padding-bottom: 10px; -} - -QComboBox#NotebookSelector QListWidget::item:hover { - color: @combobox_view_item_hover_fg; - background-color: @combobox_view_item_hover_bg; -} -/* End QComboBox */ - -/* QLabel */ -QLabel { - border: none; - color: @label_fg; - background: transparent; -} - -QLabel[TitleLabel="true"] { - padding-top: 5px; - padding-bottom: 5px; - color: @label_titlelabel_fg; - background-color: @label_titlelabel_bg; -} - -QLabel[ColorRedLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #D32F2F; -} - -QLabel[ColorGreenLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #388E3C; -} - -QLabel[ColorGreyLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #616161; -} - -QLabel[ColorTealLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #00796B; -} - -QLabel[MenuSeparator="true"] { - padding-top: 5px; - padding-bottom: 5px; - margin-top: 3px; - font: italic; - border-top: 1px solid @menu_separator_bg -} - -VVimIndicator QLabel[VimIndicatorKeyLabel="true"] { - font: bold; - color: @vim_indicator_key_label_fg; - background: transparent; -} - -VVimIndicator QLabel[VimIndicatorModeLabel="true"] { - padding: 0px 2px 0px 2px; - font: bold; - color: @vim_indicator_mode_label_fg; - /* background color will be controlled by the code. */ -} - -VTabIndicator QLabel[TabIndicatorLabel="true"] { - color: @tab_indicator_label_fg; - background: transparent; -} -/* End QLabel */ - -/* QLineEdit */ -QLineEdit { - border: 1px solid @lineedit_border; - padding: 3px; - color: @lineedit_fg; - background: @lineedit_bg; - selection-color: @lineedit_selection_fg; - selection-background-color: @lineedit_selection_bg; -} - -QLineEdit:focus { - border: 2px solid @lineedit_focus_border; - background: @lineedit_focus_bg; -} - -QLineEdit[VimCommandLine="true"] { - padding: 0px; - margin: 0px; - border: none; - color: @lineedit_fg; - background: @lineedit_bg; -} - -QLineEdit[VimCommandLine="true"]:focus { - background: @lineedit_focus_bg; -} -/* End QLineEdit */ - -/* QPlainTextEdit QTextEdit */ -QPlainTextEdit[LineEdit="true"], QTextEdit[LineEdit="true"] { - border: 1px solid @lineedit_border; - padding: 3px; - color: @lineedit_fg; - background: @lineedit_bg; - selection-color: @lineedit_selection_fg; - selection-background-color: @lineedit_selection_bg; -} - -QPlainTextEdit[LineEdit="true"]:focus, QTextEdit[LineEdit="true"]:focus { - border: 2px solid @lineedit_focus_border; - background: @lineedit_focus_bg; -} -/* End QPlainTextEdit QTextEdit */ - -/* QTabWidget */ -QTabWidget { - border: none; -} - -QTabWidget::pane { - border: none; -} -/* End QTabWidget */ - -/* QTabBar */ -QTabBar::tab { - color: @tabbar_fg; - background: @tabbar_bg; - border: none; - border-top: 2px solid transparent; - border-right: 1px solid @tabbar_border; - padding: 2px; -} - -QTabBar::tab:selected { - color: @tabbar_selected_fg; - background: @tabbar_selected_bg; - border-top: 2px solid @master_bg; -} - -QTabBar::tab:hover { - color: @tabbar_hover_fg; - background: @tabbar_hover_bg; -} - -QTabBar::close-button { - image: url(close_grey.svg); -} - -QTabBar::close-button:hover { - image: url(close.svg); -} - -QTabBar::close-button:focus { - image: url(close.svg); -} - -QTabBar::scroller { - width: 20px; -} - -QTabBar QToolButton { - border: none; -} - -QTabBar QToolButton::right-arrow:enabled { - image: url(right.svg); -} - -QTabBar QToolButton::left-arrow:enabled { - image: url(left.svg); -} - -QTabBar QToolButton::right-arrow:disabled { - image: url(right_disabled.svg); -} - -QTabBar QToolButton::left-arrow:disabled { - image: url(left_disabled.svg); -} -/* End QTabBar */ - -VSelectorItemWidget QLabel[SelectorItemShortcutLabel="true"] { - font: bold; - border: 2px solid @selectoritem_border; - padding: 3px; - border-radius: 5px; - background-color: @selectoritem_bg; - color: @selectoritem_fg; -} - -VInsertSelector { - border: none; - background: @insertselector_bg; -} - -/* QTreeView */ -QTreeView { - color: @treeview_fg; - background: @treeview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QTreeView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QTreeView[ItemBorder="true"]::item { - padding-top: 5px; - padding-bottom: 5px; - border-bottom: 1px solid @treeview_item_border_bg; -} - -QTreeView::item:hover { - color: @treeview_item_hover_fg; - background: @treeview_item_hover_bg; -} - -QTreeView::item:selected { - color: @treeview_item_selected_fg; - background: @treeview_item_selected_bg; -} - -QTreeView::item:selected:active { - color: @treeview_item_selected_active_fg; - background: @treeview_item_selected_active_bg; -} - -QTreeView::item:selected:!active { - color: @treeview_item_selected_inactive_fg; - background: @treeview_item_selected_inactive_bg; -} - -QTreeView::branch:has-siblings:!adjoins-item { - border-image: url(line.svg) 0; -} - -QTreeView::branch:has-siblings:adjoins-item { - border-image: url(branch_more.svg) 0; -} - -QTreeView::branch:!has-children:!has-siblings:adjoins-item { - border-image: url(branch_end.svg) 0; -} - -QTreeView::branch:has-children:!has-siblings:closed, -QTreeView::branch:closed:has-children:has-siblings { - border-image: none; - image: url(branch_closed.svg); -} - -QTreeView::branch:open:has-children:!has-siblings, -QTreeView::branch:open:has-children:has-siblings { - border-image: none; - image: url(branch_open.svg); -} - -QTreeView[PlainTree="true"]::branch:has-siblings:!adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:has-siblings:adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:!has-children:!has-siblings:adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:has-children:!has-siblings:closed, -QTreeView[PlainTree="true"]::branch:closed:has-children:has-siblings { - border-image: none; - image: none; -} - -QTreeView[PlainTree="true"]::branch:open:has-children:!has-siblings, -QTreeView[PlainTree="true"]::branch:open:has-children:has-siblings { - border-image: none; - image: none; -} -/* End QTreeView */ - -/* QListView */ -QListView { - color: @listview_fg; - background: @listview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QListView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QListView::item:hover { - color: @listview_item_hover_fg; - background: @listview_item_hover_bg; -} - -QListView::item:selected { - color: @listview_item_selected_fg; - background: @listview_item_selected_bg; -} - -QListView::item:selected:active { - color: @listview_item_selected_active_fg; - background: @listview_item_selected_active_bg; -} - -QListView::item:selected:!active { - color: @listview_item_selected_inactive_fg; - background: @listview_item_selected_inactive_bg; -} -/* End QListView */ - -/* QSplitter */ -QSplitter { - border: none; -} - -QSplitter::handle { - background-color: @splitter_handle_bg; -} - -QSplitter::handle:vertical { - height: 2px; -} - -QSplitter::handle:horizontal { - width: 2px; -} - -QSplitter#MainSplitter { - border: none; -} -/* End QSplitter */ - -/* QStatusBar */ -QStatusBar { - color: @statusbar_fg; - background: @statusbar_bg; -} -/* End QStatusBar */ - -QWidget[MainEditor="true"] { - border: none; -} - -QDialog { - color: @base_fg; - background: @base_bg; -} - -/* QScrollBar */ -QScrollBar::add-page, QScrollBar::sub-page { - background: @scrollbar_page_bg; -} - -QScrollBar:vertical { - background: @scrollbar_bg; - width: 16px; - margin: 16px 0px 16px 0px; - padding: 0px 2px 0px 2px; - border: none; -} - -QScrollBar::handle:vertical { - background: @scrollbar_handle_bg; - min-height: 16px; -} - -QScrollBar::handle:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:vertical { - border: none; - background: @scrollbar_bg; - width: 16px; - height: 16px; - subcontrol-position: bottom; - subcontrol-origin: margin; -} - -QScrollBar::add-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:vertical { - border: none; - background: @scrollbar_bg; - width: 16px; - height: 16px; - subcontrol-position: top; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::down-arrow:vertical { - image: url(down.svg); - width: 16px; - height: 16px; -} - -QScrollBar::up-arrow:vertical { - image: url(up.svg); - width: 16px; - height: 16px; -} - -QScrollBar:horizontal { - background: @scrollbar_bg; - height: 16px; - margin: 0px 16px 0px 16px; - padding: 2px 0px 2px 0px; - border: none; -} - -QScrollBar::handle:horizontal { - background: @scrollbar_handle_bg; - min-width: 16px; -} - -QScrollBar::handle:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:horizontal { - border: none; - background: @scrollbar_bg; - width: 16px; - height: 16px; - subcontrol-position: right; - subcontrol-origin: margin; -} - -QScrollBar::add-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:horizontal { - border: none; - background: @scrollbar_bg; - width: 16px; - height: 16px; - subcontrol-position: left; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::right-arrow:horizontal { - image: url(right.svg); - width: 16px; - height: 16px; -} - -QScrollBar::left-arrow:horizontal { - image: url(left.svg); - width: 16px; - height: 16px; -} -/* End QScrollBar */ - -/* QCheckBox */ -QCheckBox { - spacing: 5px; -} - -QCheckBox::indicator { - width: 20px; - height: 20px; -} - -QCheckBox::indicator:unchecked { - image: url(checkbox_unchecked.svg); -} - -QCheckBox::indicator:unchecked:hover { - background: @checkbox_indicator_hover_bg; -} - -QCheckBox::indicator:unchecked:pressed { - background: @checkbox_indicator_pressed_bg; -} - -QCheckBox::indicator:checked { - image: url(checkbox_checked.svg); -} - -QCheckBox::indicator:checked:hover { - background: @checkbox_indicator_hover_bg; -} - -QCheckBox::indicator:checked:pressed { - background: @checkbox_indicator_pressed_bg; -} - -QCheckBox::indicator:indeterminate:hover { - background: @checkbox_indicator_hover_bg; -} - -QCheckBox::indicator:indeterminate:pressed { - background: @checkbox_indicator_pressed_bg; -} -/* End QCheckBox */ - -/* QRadioButton */ -QRadioButton { - spacing: 5px; -} - -QRadioButton::indicator { - width: 20px; - height: 20px; -} - -QRadioButton::indicator:unchecked { - image: url(radiobutton_unchecked.svg); -} - -QRadioButton::indicator:unchecked:hover { - background: @radiobutton_indicator_hover_bg; -} - -QRadioButton::indicator:unchecked:pressed { - background: @radiobutton_indicator_pressed_bg; -} - -QRadioButton::indicator:checked { - image: url(radiobutton_checked.svg); -} - -QRadioButton::indicator:checked:hover { - background: @radiobutton_indicator_hover_bg; -} - -QRadioButton::indicator:checked:pressed { - background: @radiobutton_indicator_pressed_bg; -} -/* End QRadioButton */ - -/* QSpinBox */ -QSpinBox, QDoubleSpinBox { - border: 1px solid @spinbox_border; - color: @spinbox_fg; - background: @spinbox_bg; - padding-right: 25px; - min-height: 25px; - selection-color: @spinbox_selection_fg; - selection-background-color: @spinbox_selection_bg; -} - -QSpinBox:focus, QDoubleSpinBox::focus { - border: 2px solid @spinbox_focus_border; - background: @spinbox_focus_bg; -} - -QSpinBox::up-button, QDoubleSpinBox::up-button { - subcontrol-origin: border; - subcontrol-position: top right; /* position at the top right corner */ - width: 25px; - border: none; - background: transparent; -} - -QSpinBox::up-button:hover, QDoubleSpinBox::up-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::up-button:pressed, QDoubleSpinBox::up-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::up-arrow, QDoubleSpinBox::up-arrow { - image: url(up.svg); - width: 12px; - height: 12px; -} - -QSpinBox::up-arrow:disabled, QSpinBox::up-arrow:off, QDoubleSpinBox::up-arrow:disabled, QDoubleSpinBox::up-arrow:off { - image: url(up_disabled.svg); -} - -QSpinBox::down-button, QDoubleSpinBox::down-button { - subcontrol-origin: border; - subcontrol-position: bottom right; /* position at the top right corner */ - width: 25px; - border: none; - background: transparent; -} - -QSpinBox::down-button:hover, QDoubleSpinBox::down-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::down-button:pressed, QDoubleSpinBox::down-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::down-arrow, QDoubleSpinBox::down-arrow { - image: url(down.svg); - width: 12px; - height: 12px; -} - -QSpinBox::down-arrow:disabled, QSpinBox::down-arrow:off, QDoubleSpinBox::down-arrow:disabled, QDoubleSpinBox::down-arrow:off { - image: url(down_disabled.svg); -} -/* End QSpinBox */ - -/* QHeaderView */ -QHeaderView::section { - background: @headerview_bg; - color: @headerview_fg; - padding-left: 4px; - border: none; - border-left: 1px solid @headerview_border; - border-bottom: 1px solid @headerview_border; -} - -QHeaderView::section:checked -{ - color: @headerview_checked_fg; - background: @headerview_checked_bg; -} - -/* style the sort indicator */ -QHeaderView::down-arrow { - image: url(down.svg); -} - -QHeaderView::up-arrow { - image: url(up.svg); -} -/* End QHeaderView */ - -QWidget#FindReplaceTitleWidget { - background: @title_bg; -} - -QWidget[ToolBoxTitle="true"] { - border-bottom: 2px solid @toolbox_title_border; -} - -QAbstractScrollArea::corner { - background: @scrollbar_bg; - border: none; -} - -/* QProgressBar */ -QProgressBar { - background: @progressbar_bg; - border: 1px solid @progressbar_border_bg; - text-align: center; -} - -QProgressBar::chunk { - background-color: @progressbar_chunk_bg; - width: 20px; -} -/* End QProgressBar */ diff --git a/src/resources/themes/v_pure/v_pure_codeblock.css b/src/resources/themes/v_pure/v_pure_codeblock.css deleted file mode 100644 index fdf954d5..00000000 --- a/src/resources/themes/v_pure/v_pure_codeblock.css +++ /dev/null @@ -1,99 +0,0 @@ -/* - -Original highlight.js style (c) Ivan Sagalaev - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #E0E0E0; -} - - -/* Base color: saturation 0; */ - -.hljs, -.hljs-subst { - color: #363636; -} - -.hljs-comment { - color: #767676; -} - -.hljs-keyword, -.hljs-attribute, -.hljs-selector-tag, -.hljs-meta-keyword, -.hljs-doctag, -.hljs-name { - color: #0000ee; -} - - -/* User color: hue: 0 */ - -.hljs-type, -.hljs-string, -.hljs-number, -.hljs-selector-id, -.hljs-selector-class, -.hljs-quote, -.hljs-template-tag, -.hljs-deletion { - color: #880000; -} - -.hljs-title, -.hljs-section { - color: #880000; - font-weight: bold; -} - -.hljs-regexp, -.hljs-symbol, -.hljs-variable, -.hljs-template-variable, -.hljs-link, -.hljs-selector-attr, -.hljs-selector-pseudo { - color: #BC6060; -} - - -/* Language color: hue: 90; */ - -.hljs-literal { - color: #af00d7; -} - -.hljs-built_in, -.hljs-bullet, -.hljs-code, -.hljs-addition { - color: #008700; -} - - -/* Meta color: hue: 200 */ - -.hljs-meta { - color: #1f7199; -} - -.hljs-meta-string { - color: #4d99bf; -} - - -/* Misc effects */ - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/src/resources/themes/v_white/arrow_dropdown.svg b/src/resources/themes/v_white/arrow_dropdown.svg deleted file mode 100644 index 55ee520d..00000000 --- a/src/resources/themes/v_white/arrow_dropdown.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/src/resources/themes/v_white/branch_closed.svg b/src/resources/themes/v_white/branch_closed.svg deleted file mode 100644 index c524ab79..00000000 --- a/src/resources/themes/v_white/branch_closed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_white/branch_end.svg b/src/resources/themes/v_white/branch_end.svg deleted file mode 100644 index baa0c23f..00000000 --- a/src/resources/themes/v_white/branch_end.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 2 - - - - diff --git a/src/resources/themes/v_white/branch_more.svg b/src/resources/themes/v_white/branch_more.svg deleted file mode 100644 index cb0fecad..00000000 --- a/src/resources/themes/v_white/branch_more.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 2 - - - - diff --git a/src/resources/themes/v_white/branch_open.svg b/src/resources/themes/v_white/branch_open.svg deleted file mode 100644 index c1e8e141..00000000 --- a/src/resources/themes/v_white/branch_open.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_white/checkbox_checked.svg b/src/resources/themes/v_white/checkbox_checked.svg deleted file mode 100644 index f017b5b4..00000000 --- a/src/resources/themes/v_white/checkbox_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_white/checkbox_unchecked.svg b/src/resources/themes/v_white/checkbox_unchecked.svg deleted file mode 100644 index 5167523e..00000000 --- a/src/resources/themes/v_white/checkbox_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_white/close.svg b/src/resources/themes/v_white/close.svg deleted file mode 100644 index aa6b81c1..00000000 --- a/src/resources/themes/v_white/close.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_white/close_grey.svg b/src/resources/themes/v_white/close_grey.svg deleted file mode 100644 index 24bddd4e..00000000 --- a/src/resources/themes/v_white/close_grey.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_white/down.svg b/src/resources/themes/v_white/down.svg deleted file mode 100644 index 386ac7f8..00000000 --- a/src/resources/themes/v_white/down.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_white/down_disabled.svg b/src/resources/themes/v_white/down_disabled.svg deleted file mode 100644 index 2a53e0f0..00000000 --- a/src/resources/themes/v_white/down_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_white/float.svg b/src/resources/themes/v_white/float.svg deleted file mode 100644 index 3c29db9a..00000000 --- a/src/resources/themes/v_white/float.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/themes/v_white/left.svg b/src/resources/themes/v_white/left.svg deleted file mode 100644 index aee69f4a..00000000 --- a/src/resources/themes/v_white/left.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_white/left_disabled.svg b/src/resources/themes/v_white/left_disabled.svg deleted file mode 100644 index 3cabd4b5..00000000 --- a/src/resources/themes/v_white/left_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_white/line.svg b/src/resources/themes/v_white/line.svg deleted file mode 100644 index 8c981419..00000000 --- a/src/resources/themes/v_white/line.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 2 - - - diff --git a/src/resources/themes/v_white/menu_checkbox.svg b/src/resources/themes/v_white/menu_checkbox.svg deleted file mode 100644 index 0aeb35a1..00000000 --- a/src/resources/themes/v_white/menu_checkbox.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_white/menu_radiobutton.svg b/src/resources/themes/v_white/menu_radiobutton.svg deleted file mode 100644 index aafaa309..00000000 --- a/src/resources/themes/v_white/menu_radiobutton.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_white/radiobutton_checked.svg b/src/resources/themes/v_white/radiobutton_checked.svg deleted file mode 100644 index c9834cc5..00000000 --- a/src/resources/themes/v_white/radiobutton_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_white/radiobutton_unchecked.svg b/src/resources/themes/v_white/radiobutton_unchecked.svg deleted file mode 100644 index 7cd0863a..00000000 --- a/src/resources/themes/v_white/radiobutton_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_white/right.svg b/src/resources/themes/v_white/right.svg deleted file mode 100644 index c524ab79..00000000 --- a/src/resources/themes/v_white/right.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_white/right_disabled.svg b/src/resources/themes/v_white/right_disabled.svg deleted file mode 100644 index c0c83ba8..00000000 --- a/src/resources/themes/v_white/right_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_white/up.svg b/src/resources/themes/v_white/up.svg deleted file mode 100644 index 52be26da..00000000 --- a/src/resources/themes/v_white/up.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_white/up_disabled.svg b/src/resources/themes/v_white/up_disabled.svg deleted file mode 100644 index 36e54158..00000000 --- a/src/resources/themes/v_white/up_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_white/v_white.css b/src/resources/themes/v_white/v_white.css deleted file mode 100644 index 2420870c..00000000 --- a/src/resources/themes/v_white/v_white.css +++ /dev/null @@ -1,296 +0,0 @@ -body { - margin: 0 auto; - font-family: Helvetica, sans-serif, Tahoma, Arial, Verdana, Geneva, Georgia, Palatino, "Times New Roman", "Hiragino Sans GB", "冬青黑体", "Microsoft YaHei", "微软雅黑", "Microsoft YaHei UI", "WenQuanYi Micro Hei", "文泉驿雅黑", Dengxian, "等线体", STXihei, "华文细黑", "Liberation Sans", "Droid Sans", NSimSun, "新宋体", SimSun, "宋体"; - color: #363636; - line-height: 1; - padding: 30px; -} - -h1, h2, h3, h4, h5, h6 { - color: #363636; - font-weight: bold; - margin-bottom: 24px; - padding: 0; -} - -p { - padding: 0; -} - -h1 { - font-size: 36px; -} - -h2 { - font-size: 30px; -} - -h3 { - font-size: 26px; -} - -h4 { - font-size: 22px; -} - -h5 { - font-size: 20px; -} - -h6 { - font-size: 18px; -} - -a { - color: #0099ff; - margin: 0; - padding: 0; - vertical-align: baseline; -} - -a:hover { - text-decoration: none; - color: #ff6600; -} - -a:visited { - color: purple; -} - -ul, ol { - padding: 0; - padding-left: 24px; -} - -li { - line-height: 24px; -} - -li ul, li ul { - margin-left: 24px; -} - -p, ul, ol { - font-size: 16px; - line-height: 24px; -} - -pre { - display: block; - overflow-y: hidden; - overflow-x: auto; -} - -code { - font-family: Consolas, Monaco, Andale Mono, Monospace, Courier New; - line-height: 1.5; - font-size: 14px; - color: #4527A0; -} - -pre code { - margin: 0; - padding: 0; - border: none; - color: #363636; -} - -aside { - display: block; - float: right; - width: 390px; -} - -blockquote { - color: #666; - border-left:.5em solid #7a7a7a; - padding: 0 2em; - margin-left:0; -} - -blockquote p { - color: #666; -} - -hr { - display: block; - text-align: left; - margin: 1em 0; - border: none; - height: 2px; - background: #999; -} - -table { - padding: 0; - border-collapse: collapse; -} - -table tr { - border-top: 1px solid #cccccc; - background-color: white; - margin: 0; - padding: 0; -} - -table tr:nth-child(2n) { - background-color: #f8f8f8; -} - -table tr th { - font-weight: bold; - border: 1px solid #cccccc; - margin: 0; - padding: 6px 13px; -} - -table tr td { - border: 1px solid #cccccc; - margin: 0; - padding: 6px 13px; -} - -table tr th :first-child, table tr td :first-child { - margin-top: 0; -} - -table tr th :last-child, table tr td :last-child { - margin-bottom: 0; -} - -div.mermaid-diagram { - overflow-y: hidden; -} - -pre.mermaid-diagram { - overflow-y: hidden; -} - -div.flowchart-diagram { - overflow-y: hidden; -} - -pre.flowchart-diagram { - overflow-y: hidden; -} - -.img-package { - text-align: center; -} - -img.img-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -div.img-caption { - min-width: 20%; - max-width: 80%; - display: inline-block; - padding: 10px; - margin: 0 auto; - border-bottom: 1px solid #c0c0c0; - color: #6c6c6c; - text-align: center; - line-height: 1.5; -} - -/* For Highlight.js Line Number */ -table.hljs-ln tr { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td.hljs-ln-numbers { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - - text-align: center; - color: #AAA; - border-right: 1px solid #CCC; - vertical-align: top; - padding-right: 5px; -} - -table.hljs-ln tr td.hljs-ln-code { - padding-left: 10px; -} - -::-webkit-scrollbar { - background-color: #EEEEEE; - width: 14px; - height: 14px; - border: none; -} - -::-webkit-scrollbar-corner { - background-color: #EEEEEE; -} - -::-webkit-scrollbar-button { - /* This selector affects the styling of both the up & down and left & right buttons of a scrollbar */ - height: 14px; - width: 14px; - background-color: #EEEEEE; -} - -::-webkit-scrollbar-button:hover { - background-color: #C0C0C0; -} - -::-webkit-scrollbar-button:active { - background-color: #808080; -} - -::-webkit-scrollbar-track { - /* This selector affects the styling of the area in the scrollbar between the two buttons */ - background-color: #EEEEEE; -} - -::-webkit-scrollbar-thumb { - /* This selector affects the styling of draggable element of the scollbar */ - border: none; - background-color: #D0D0D0; -} - -::-webkit-scrollbar-thumb:hover { - background-color: #C0C0C0; -} - -::-webkit-scrollbar-thumb:active { - background-color: #808080; -} - -::-webkit-scrollbar-button:horizontal:increment { - background-image: url(right.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:horizontal:decrement { - background-image: url(left.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:vertical:increment { - background-image: url(down.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:vertical:decrement { - background-image: url(up.svg); - background-repeat: no-repeat; - background-size: contain; -} diff --git a/src/resources/themes/v_white/v_white.mdhl b/src/resources/themes/v_white/v_white.mdhl deleted file mode 100644 index 77998917..00000000 --- a/src/resources/themes/v_white/v_white.mdhl +++ /dev/null @@ -1,167 +0,0 @@ -# This is the default markdown styles used for Peg-Markdown-Highlight -# created by Le Tan(tamlokveer@gmail.com). -# For a complete description of the syntax, please refer to the original -# documentation of the style parser -# [The Syntax of PEG Markdown Highlight Stylesheets](http://hasseg.org/peg-markdown-highlight/docs/stylesheet_syntax.html). -# VNote adds some styles in the syntax which will be marked [VNote] in the comment. -# -# Note: Empty lines within a section is NOT allowed. -# Note: Do NOT modify this file directly. Copy it and tune your own style! - -editor -# QTextEdit just choose the first available font, so specify the Chinese fonts first -# Do not use "" to quote the name -font-family: Hiragino Sans GB, 冬青黑体, Microsoft YaHei, 微软雅黑, Microsoft YaHei UI, WenQuanYi Micro Hei, 文泉驿雅黑, Dengxian, 等线体, STXihei, 华文细黑, Liberation Sans, Droid Sans, NSimSun, 新宋体, SimSun, 宋体, Helvetica, sans-serif, Tahoma, Arial, Verdana, Geneva, Georgia, Times New Roman -font-size: 12 -foreground: 363636 -# [VNote] Style for trailing space -trailing-space: a8a8a8 -# [VNote] Style for line number -line-number-background: f5f5f5 -line-number-foreground: 424242 -# [VNote] Style for selected word highlight -selected-word-background: dfdf00 -# [VNote] Style for searched word highlight -searched-word-background: 4db6ac -# [VNote] Style for searched word under cursor highlight -searched-word-cursor-background: 66bb6a -# [VNote] Style for incremental searched word highlight -incremental-searched-word-background: ce93d8 -# [VNote] Style for color column in fenced code block -color-column-background: dd0000 -color-column-foreground: ffff00 -# [VNote} Style for preview image line -preview-image-line-foreground: 9575cd - -editor-selection -foreground: eeeeee -background: 005fff - -editor-current-line -background: c5cae9 -# [VNote] Vim insert mode cursor line background -vim-insert-background: c5cae9 -# [VNote] Vim normal mode cursor line background -vim-normal-background: c0c0c0 -# [VNote] Vim visual mode cursor line background -vim-visual-background: 90caf9 -# [VNote] Vim replace mode cursor line background -vim-replace-background: f8bbd0 - -H1 -foreground: 363636 -font-style: bold -font-size: +8 - -H2 -foreground: 363636 -font-style: bold -font-size: +6 - -H3 -foreground: 363636 -font-style: bold -font-size: +4 - -H4 -foreground: 363636 -font-style: bold -font-size: +2 - -H5 -foreground: 363636 -font-style: bold -font-size: +2 - -H6 -foreground: 363636 -font-style: bold -font-size: +2 - -HRULE -foreground: 586e75 - -LIST_BULLET -foreground: d33682 -font-style: bold -font-size: +2 - -LIST_ENUMERATOR -foreground: 0000ff - -LINK -foreground: 005fff - -AUTO_LINK_URL -foreground: 005fff - -AUTO_LINK_EMAIL -foreground: 005fff - -IMAGE -foreground: 616161 - -REFERENCE -foreground: b58900 - -CODE -foreground: 551a8b -font-family: Consolas, Monaco, Andale Mono, Monospace, Courier New - -EMPH -font-style: italic - -STRONG -font-style: bold - -HTML_ENTITY -foreground: 6c71c4 - -COMMENT -foreground: 93a1a1 - -VERBATIM -foreground: 551a8b -font-family: Consolas, Monaco, Andale Mono, Monospace, Courier New -# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, color) -# The last occurence of the same attribute takes effect -hljs-comment: 6c6c6c -hljs-keyword: 0000ee -hljs-attribute: 0000ee -hljs-selector-tag: 0000ee -hljs-meta-keyword: 0000ee -hljs-doctag: 0000ee -hljs-name: 0000ee -hljs-type: 880000 -hljs-string: 880000 -hljs-number: 880000 -hljs-selector-id: 880000 -hljs-selector-class: 880000 -hljs-quote: 880000 -hljs-template-tag: 880000 -hljs-deletion: 880000 -# Could specify multiple attribute in one line -hljs-title: bold, 880000 -hljs-section: bold, 880000 -hljs-regexp: bc6060 -hljs-symbol: bc6060 -hljs-variable: bc6060 -hljs-template-variable: bc6060 -hljs-link: bc6060 -hljs-selector-attr: bc6060 -hljs-selector-pseudo: bc6060 -hljs-literal: af00d7 -hljs-built_in: 008700 -hljs-bullet: 008700 -hljs-code: 008700 -hljs-addition: 008700 -hljs-meta: 1f7199 -hljs-meta-string: 4d99bf -hljs-emphasis: italic -hljs-strong: bold - -BLOCKQUOTE -foreground: 00af00 - -STRIKE -strike-color: 586e75 diff --git a/src/resources/themes/v_white/v_white.palette b/src/resources/themes/v_white/v_white.palette deleted file mode 100644 index 5b47cadc..00000000 --- a/src/resources/themes/v_white/v_white.palette +++ /dev/null @@ -1,298 +0,0 @@ -; File path could be absolute path or relative path (related to this file). -; Use @color_tag to reference a style. - -[metadata] -qss_file=v_white.qss -mdhl_file=v_white.mdhl -css_file=v_white.css -codeblock_css_file=v_white_codeblock.css - -[phony] -; Abstract color attributes. -base_fg=#000000 -base_bg=#F5F5F5 - -main_fg=#000000 -main_bg=#F5F5F5 - -title_fg=#000000 -title_bg=#DADBDB - -hover_fg=#000000 -hover_bg=#C0C0C0 - -selected_fg=#000000 -selected_bg=#BCBCBC - -active_fg=#000000 -active_bg=#C0C0C0 - -inactive_fg=#000000 -inactive_bg=#D3D3D3 - -focus_fg=#000000 -focus_bg=#A9A9A9 - -pressed_fg=#000000 -pressed_bg=#808080 - -disabled_fg=#BCBCBC - -separator_bg=#C0C0C0 - -border_bg=#C0C0C0 - -content_fg=#000000 -content_bg=#FFFFFF - -selection_fg=#000000 -selection_bg=#64b5f6 - -icon_fg=#222222 -icon_disabled_fg=@disabled_fg - -danger_fg=#F5F5F5 -danger_bg=#C9302C -danger_focus_bg=#D9534F -danger_hover_bg=#D9534F -danger_pressed_bg=#AC2925 - -[soft_defined] -; VAvatar. -avatar_border_bg=@title_bg -avatar_fg=@base_bg -avatar_bg=@base_fg -; The border background color of the avatar when Captain mode is triggered. -avatar_captain_mode_border_bg=#6C6C6C - -; Style of the label in Navigation mode. -navigation_label_fg=#4D4D4D -navigation_label_bg=#F4F4F4 - -; Style of the bubble of VButtonWithWidget. -bubble_fg=#FFFFFF -bubble_bg=#616161 - -; Icons' foreground. -danger_icon_fg=@danger_bg -item_icon_fg=@icon_fg -title_icon_fg=@icon_fg - -; VVimIndicator. -vim_indicator_key_label_fg=@base_fg -vim_indicator_mode_label_fg=@base_fg -vim_indicator_cmd_edit_pending_bg=@selected_bg - -; VTabIndicator. -tab_indicator_label_fg=@base_fg - -; Html template. -template_title_flash_light_fg=#80CBC4 -template_title_flash_dark_fg=#00897B - -[widgets] -; Widget color attributes. - -; QWidget. -widget_fg=@base_fg - -; Separator of dock widgets. -dock_separator_bg=@title_bg -dock_separator_hover_bg=@title_bg - -; Menubar. -menubar_bg=@main_bg -menubar_fg=@main_fg -menubar_item_selected_bg=@selected_bg - -; Menu. -menu_bg=@base_bg -menu_fg=@base_fg -menu_item_disabled_fg=@disabled_fg -menu_item_selected_fg=@selected_fg -menu_item_selected_bg=@selected_bg -menu_separator_bg=@separator_bg -menu_icon_fg=@icon_fg -menu_icon_danger_fg=@danger_icon_fg - -; Tooltip. -tooltip_border=@border_bg -tooltip_bg=@base_bg -tooltip_fg=@base_fg - -; Toolbar. -toolbar_bg=@main_bg -toolbutton_hover_bg=@hover_bg -toolbutton_pressed_bg=@pressed_bg -toolbutton_checked_bg=@selected_bg -toolbutton_icon_fg=@icon_fg -toolbutton_icon_danger_fg=@danger_icon_fg - -; Toolbox. -toolbox_icon_fg=@icon_fg -toolbox_icon_active_fg=@icon_fg - -; Dockwidget. -dockwidget_title_fg=@title_fg -dockwidget_title_bg=@title_bg -dockwidget_button_hover_bg=@hover_bg - -; PushButton. -pushbutton_fg=@base_fg -pushbutton_bg=transparent -pushbutton_border=@border_bg -pushbutton_pressed_bg=@pressed_bg -pushbutton_checked_bg=@selected_bg -pushbutton_hover_bg=@hover_bg -pushbutton_default_border=#424242 -pushbutton_disabled_fg=@disabled_fg -pushbutton_disabled_bg=@pushbutton_bg - -pushbutton_cornerbtn_hover_bg=@hover_bg -pushbutton_cornerbtn_focus_bg=@focus_bg -pushbutton_cornerbtn_pressed_bg=@pressed_bg - -pushbutton_statusbtn_hover_bg=@hover_bg -pushbutton_statusbtn_focus_bg=@focus_bg -pushbutton_statusbtn_pressed_bg=@pressed_bg - -pushbutton_flatbtn_hover_bg=@hover_bg -pushbutton_flatbtn_focus_bg=@focus_bg -pushbutton_flatbtn_pressed_bg=@pressed_bg - -pushbutton_selectionbtn_hover_bg=@hover_bg -pushbutton_selectionbtn_focus_bg=@focus_bg -pushbutton_selectionbtn_pressed_bg=@pressed_bg - -pushbutton_titlebtn_bg=@title_bg -pushbutton_titlebtn_hover_bg=@hover_bg -pushbutton_titlebtn_focus_bg=@focus_bg -pushbutton_titlebtn_pressed_bg=@pressed_bg - -pushbutton_dangerbtn_fg=@danger_fg -pushbutton_dangerbtn_bg=@danger_bg -pushbutton_dangerbtn_hover_bg=@danger_hover_bg -pushbutton_dangerbtn_focus_bg=@danger_focus_bg -pushbutton_dangerbtn_pressed_bg=@danger_pressed_bg - -button_icon_fg=@icon_fg -button_icon_danger_fg=@danger_icon_fg - -; ComboBox. -combobox_border=@border_bg -combobox_fg=@content_fg -combobox_bg=@content_bg -combobox_view_border=@border_bg -combobox_view_selected_bg=@selected_bg -combobox_view_selected_fg=@selected_fg -combobox_view_item_hover_fg=@hover_fg -combobox_view_item_hover_bg=@hover_bg -combobox_focus_bg=@focus_bg -combobox_item_icon_fg=@item_icon_fg - -; Label. -label_fg=@base_fg -label_titlelabel_fg=@title_fg -label_titlelabel_bg=@title_bg - -; LineEdit. -lineedit_border=@border_bg -lineedit_fg=@content_fg -lineedit_bg=@content_bg -lineedit_selection_fg=@selection_fg -lineedit_selection_bg=@selection_bg - -; TabWidget. -tabwidget_pane_border=@selected_bg - -; TabBar. -tabbar_fg=@base_fg -tabbar_bg=@base_bg -tabbar_border=@border_bg - -tabbar_selected_fg=@selected_fg -tabbar_selected_bg=@selected_bg -tabbar_selected_border=@border_bg - -tabbar_hover_fg=@hover_fg -tabbar_hover_bg=@hover_bg -tabbar_hover_border=@border_bg - -tabbar_closebutton_hover_bg=@hover_bg -tabbar_closebutton_focus_bg=@focus_bg - -tabbar_icon_fg=@icon_fg -tabbar_icon_special_fg=@danger_bg - -; SelectorItem. -selectoritem_border=@base_fg -selectoritem_fg=@base_fg -selectoritem_bg=@base_bg - -; InsertSelector. -insertselector_bg=@base_bg - -; TreeView. -treeview_fg=@content_fg -treeview_bg=@content_bg -treeview_item_border_bg=@border_bg -treeview_item_hover_fg=@hover_fg -treeview_item_hover_bg=@hover_bg -treeview_item_selected_fg=@selected_fg -treeview_item_selected_bg=@selected_bg -treeview_item_selected_avtive_fg=@active_fg -treeview_item_selected_avtive_bg=@active_bg -treeview_item_selected_inactive_fg=@inactive_fg -treeview_item_selected_inactive_bg=@inactive_bg -treeview_item_icon_fg=@item_icon_fg - -; ListView. -listview_fg=@content_fg -listview_bg=@content_bg -listview_item_hover_fg=@hover_fg -listview_item_hover_bg=@hover_bg -listview_item_selected_fg=@selected_fg -listview_item_selected_bg=@selected_bg -listview_item_selected_avtive_fg=@active_fg -listview_item_selected_avtive_bg=@active_bg -listview_item_selected_inactive_fg=@inactive_fg -listview_item_selected_inactive_bg=@inactive_bg - -; Splitter. -splitter_handle_bg=@title_bg - -; StatusBar. -statusbar_fg=@main_fg -statusbar_bg=@main_bg - -; ScrollBar. -scrollbar_bg=#EEEEEE -scrollbar_handle_bg=#D0D0D0 -scrollbar_handle_hover_bg=@hover_bg -scrollbar_handle_pressed_bg=@pressed_bg - -; VEditWindow. -editwindow_corner_icon_fg=@icon_fg -editwindow_corner_icon_inactive_fg=#808080 - -; CheckBox. -checkbox_indicator_hover_bg=@hover_bg -checkbox_indicator_pressed_bg=@pressed_bg - -; RadioButton. -radiobutton_indicator_hover_bg=@hover_bg -radiobutton_indicator_pressed_bg=@pressed_bg - -; SpinBox. -spinbox_fg=@content_fg -spinbox_bg=@content_bg -spinbox_border=@border_bg -spinbox_button_hover_bg=@hover_bg -spinbox_button_pressed_bg=@pressed_bg - -; HeaderView. -headerview_bg=@base_bg -headerview_fg=@base_fg -headerview_border=@border_bg -headerview_checked_fg=@selected_fg -headerview_checked_bg=@selected_bg diff --git a/src/resources/themes/v_white/v_white.qss b/src/resources/themes/v_white/v_white.qss deleted file mode 100644 index 59bab893..00000000 --- a/src/resources/themes/v_white/v_white.qss +++ /dev/null @@ -1,1149 +0,0 @@ -QToolTip -{ - border: 1px solid @tooltip_border; - background: @tooltip_bg; - color: @tooltip_fg; -} - -/* QWidget */ -QWidget -{ - color: @widget_fg; - font-family: "Hiragino Sans GB", "冬青黑体", "Microsoft YaHei", "微软雅黑", "Microsoft YaHei UI", "WenQuanYi Micro Hei", "文泉驿雅黑", "Dengxian", "等线体", "STXihei", "华文细黑", "Liberation Sans", "Droid Sans", "NSimSun", "新宋体", "SimSun", "宋体", "Helvetica", "sans-serif", "Tahoma", "Arial", "Verdana", "Geneva", "Georgia", "Times New Roman"; -} - -QWidget[NotebookPanel="true"] { - padding-left: 3px; -} -/* End QWidget */ - -/* QMainWindow */ -QMainWindow { - color: @base_fg; - background: @base_bg; -} - -QMainWindow::separator { - background: @dock_separator_bg; - width: 2px; - height: 2px; -} - -QMainWindow::separator:hover { - background: @dock_separator_hover_bg; -} -/* End QMainWindow */ - -QMenuBar { - border: none; - background: @menubar_bg; - color: @menubar_fg; -} - -QMenuBar::item:selected { - background: @menubar_item_selected_bg; -} - -/* QMenu */ -QMenu { - background: @menu_bg; - color: @menu_fg; - margin: 2px; -} - -QMenu::icon { - margin: 5px; -} - -QMenu::item { - padding: 5px 30px 5px 30px; - border: 1px solid transparent; -} - -QMenu::item:disabled { - color: @menu_item_disabled_fg; -} - -QMenu::item:selected { - color: @menu_item_selected_fg; - background: @menu_item_selected_bg; -} - -QMenu::icon:checked { /* appearance of a 'checked' icon */ - border: 2px solid @menu_fg; -} - -QMenu::separator { - height: 2px; - background: @menu_separator_bg; - margin-left: 10px; - margin-right: 5px; -} - -QMenu::indicator { - width: 20px; - height: 20px; -} - -QMenu::indicator:non-exclusive:unchecked { - image: none; -} - -QMenu::indicator:non-exclusive:checked { - image: url(menu_checkbox.svg); -} - -QMenu::indicator:exclusive:unchecked { - image: none; -} - -QMenu::indicator:exclusive:checked { - image: url(menu_radiobutton.svg); -} -/* End QMenu */ - -QToolBar { - border: none; - background: @toolbar_bg; -} - -/* QToolButton */ -QToolButton { - border: none; - background: transparent; - margin: 1px 3px 1px 3px; - padding: 0px; -} - -QToolButton[popupMode="1"] { /* only for MenuButtonPopup */ - padding-right: 16px; /* make way for the popup button */ -} - -QToolButton[popupMode="2"] { /* only for InstantPopup */ - padding-right: 10px; /* make way for the popup button */ -} - -QToolButton:hover { - border:none; - background: @toolbutton_hover_bg; -} - -QToolButton:pressed { - background: @toolbutton_pressed_bg; -} - -QToolButton:checked { - background: @toolbutton_checked_bg; -} - -QToolButton:checked:hover { - background: @toolbutton_hover_bg; -} - -/* the subcontrols below are used only in the MenuButtonPopup mode */ -QToolButton::menu-button { - border: none; - width: 16px; -} - -QToolButton::menu-arrow { - image: url(arrow_dropdown.svg); - width: 16px; - height: 16px; -} -/* End QToolButton*/ - -/* DockWidget */ -QDockWidget { - color: @dockwidget_title_fg; - titlebar-close-icon: url(close.svg); - titlebar-normal-icon: url(float.svg); -} - -QDockWidget::Title { - background: @dockwidget_title_bg; - text-align: center left; -} - -QDockWidget::close-button, QDockWidget::float-button { - border: none; -} - -QDockWidget::close-button:hover, QDockWidget::float-button:hover { - background: @dockwidget_button_hover_bg; -} -/* End DockWidget */ - -/* QPushButton */ -QPushButton { - color: @pushbutton_fg; - background: @pushbutton_bg; - border: 1px solid @pushbutton_border; - padding: 3px; - min-width: 80px; -} - -QPushButton:pressed { - background-color: @pushbutton_pressed_bg; -} - -QPushButton:checked { - background-color: @pushbutton_checked_bg; -} - -QPushButton:checked:hover { - background-color: @pushbutton_hover_bg; -} - -QPushButton:hover { - background-color: @pushbutton_hover_bg; -} - -QPushButton:flat { - border: none; -} - -QPushButton:default { - border-color: @pushbutton_default_border; -} - -QPushButton:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton::menu-indicator { - image: url(arrow_dropdown.svg); - width: 16px; - height: 16px; -} - -QPushButton[CornerBtn="true"] { - padding: 4px -2px 4px -2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[CornerBtn="true"]::menu-indicator { - image: none; -} - -QPushButton[CornerBtn="true"]:hover { - background-color: @pushbutton_cornerbtn_hover_bg; -} - -QPushButton[CornerBtn="true"]:focus { - background-color: @pushbutton_cornerbtn_focus_bg; -} - -QPushButton[CornerBtn="true"]:pressed { - background-color: @pushbutton_cornerbtn_pressed_bg; -} - -QPushButton[CornerBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[StatusBtn="true"] { - font: bold; - padding: 0px 2px 0px 2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[StatusBtn="true"]:hover { - background-color: @pushbutton_statusbtn_hover_bg; -} - -QPushButton[StatusBtn="true"]:focus { - background-color: @pushbutton_statusbtn_focus_bg;; -} - -QPushButton[StatusBtn="true"]:pressed { - background-color: @pushbutton_statusbtn_pressed_bg; -} - -QPushButton[StatusBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[FlatBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[FlatBtn="true"]:hover { - background-color: @pushbutton_flatbtn_hover_bg; -} - -QPushButton[FlatBtn="true"]:focus { - background-color: @pushbutton_flatbtn_focus_bg; -} - -QPushButton[FlatBtn="true"]:pressed { - background-color: @pushbutton_flatbtn_pressed_bg; -} - -QPushButton[FlatBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[SelectionBtn="true"] { - padding: 4px 10px 4px 10px; - border: none; - background-color: transparent; - font-size: 15pt; - text-align: left; - min-width: -1; -} - -QPushButton[SelectionBtn="true"]:hover { - background-color: @pushbutton_selectionbtn_hover_bg; -} - -QPushButton[SelectionBtn="true"]:focus { - background-color: @pushbutton_selectionbtn_focus_bg; -} - -QPushButton[SelectionBtn="true"]:pressed { - background-color: @pushbutton_selectionbtn_pressed_bg; -} - -QPushButton[SelectionBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[TitleBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: @pushbutton_titlebtn_bg; - min-width: -1; -} - -QPushButton[TitleBtn="true"]:hover { - background-color: @pushbutton_titlebtn_hover_bg; -} - -QPushButton[TitleBtn="true"]:focus { - background-color: @pushbutton_titlebtn_focus_bg; -} - -QPushButton[TitleBtn="true"]:pressed { - background-color: @pushbutton_titlebtn_pressed_bg; -} - -QPushButton[TitleBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[DangerBtn="true"] { - color: @pushbutton_dangerbtn_fg; - border: none; - background-color: @pushbutton_dangerbtn_bg; - min-width: -1; -} - -QPushButton[DangerBtn="true"]:hover { - background-color: @pushbutton_dangerbtn_hover_bg; -} - -QPushButton[DangerBtn="true"]:focus { - background-color: @pushbutton_dangerbtn_focus_bg; -} - -QPushButton[DangerBtn="true"]:pressed { - background-color: @pushbutton_dangerbtn_pressed_bg; -} - -QPushButton[DangerBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -VButtonMenuItem { - padding: 5px; - padding-right: 30px; - border: 1px solid transparent; - background-color: transparent; - min-width: -1; - text-align: left; -} - -VButtonMenuItem[Heading1="true"] { - font-size: 22pt; -} - -VButtonMenuItem[Heading2="true"] { - font-size: 20pt; -} - -VButtonMenuItem[Heading3="true"] { - font-size: 18pt; -} - -VButtonMenuItem[Heading4="true"] { - font-size: 16pt; -} - -VButtonMenuItem[Heading5="true"] { - font-size: 14pt; -} - -VButtonMenuItem[Heading6="true"] { - font-size: 14pt; -} - -VButtonMenuItem:hover { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:focus { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} -/* End QPushButton*/ - -/* QComboBox */ -QComboBox { - padding: 3px; - color: @combobox_fg; - background: @combobox_bg; - border: 1px solid @combobox_border; -} - -QComboBox:focus { - background-color: @combobox_focus_bg; -} - -QComboBox::drop-down { - subcontrol-origin: padding; - subcontrol-position: top right; - width: 20px; - border: none; - background: transparent; -} - -QComboBox::down-arrow { - image: url(arrow_dropdown.svg); - width: 20px; - height: 20px; -} - -QComboBox QAbstractItemView { - padding: 2px; - border: 1px solid @combobox_view_border; - background: @combobox_bg; - selection-color: @combobox_view_selected_fg; - selection-background-color: @combobox_view_selected_bg; -} - -QComboBox QAbstractItemView::item { - background: transparent; - padding: 3px; -} - -QComboBox QAbstractItemView::item:hover { - color: @combobox_view_item_hover_fg; - background: @combobox_view_item_hover_bg; -} - -QComboBox#NotebookSelector { - border: none; - font-size: 13pt; - padding-top: 3px; - padding-bottom: 3px; - icon-size: 30px; -} - -QComboBox#NotebookSelector QListWidget { - border: 1px solid @combobox_view_border; - background-color: @combobox_bg; - font-size: 13pt; - icon-size: 30px; -} - -QComboBox#NotebookSelector QListWidget::item { - padding-top: 10px; - padding-bottom: 10px; -} - -QComboBox#NotebookSelector QListWidget::item:hover { - color: @combobox_view_item_hover_fg; - background-color: @combobox_view_item_hover_bg; -} -/* End QComboBox */ - -/* QLabel */ -QLabel { - border: none; - color: @label_fg; - background: transparent; -} - -QLabel[TitleLabel="true"] { - padding-top: 5px; - padding-bottom: 5px; - color: @label_titlelabel_fg; - background-color: @label_titlelabel_bg; -} - -QLabel[ColorRedLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #D32F2F; -} - -QLabel[ColorGreenLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #388E3C; -} - -QLabel[ColorGreyLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #616161; -} - -QLabel[ColorTealLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #00796B; -} - -QLabel[MenuSeparator="true"] { - padding-top: 5px; - padding-bottom: 5px; - margin-top: 3px; - font: italic; - border-top: 1px solid @menu_separator_bg -} - -VVimIndicator QLabel[VimIndicatorKeyLabel="true"] { - font: bold; - color: @vim_indicator_key_label_fg; - background: transparent; -} - -VVimIndicator QLabel[VimIndicatorModeLabel="true"] { - padding: 0px 2px 0px 2px; - font: bold; - color: @vim_indicator_mode_label_fg; - /* background color will be controlled by the code. */ -} - -VTabIndicator QLabel[TabIndicatorLabel="true"] { - color: @tab_indicator_label_fg; - background: transparent; -} -/* End QLabel */ - -/* QLineEdit */ -QLineEdit { - border: 1px solid @lineedit_border; - padding: 3px; - color: @lineedit_fg; - background: @lineedit_bg; - selection-color: @lineedit_selection_fg; - selection-background-color: @lineedit_selection_bg; -} - -QLineEdit[VimCommandLine="true"] { - padding: 0px; - margin: 0px; - border: none; - color: @lineedit_fg; - background: @lineedit_bg; -} -/* End QLineEdit */ - -/* QTabWidget */ -QTabWidget { - border: none; -} - -QTabWidget::pane { - border: none; - border-top: 3px solid @tabwidget_pane_border; -} -/* End QTabWidget */ - -/* QTabBar */ -QTabBar::tab { - color: @tabbar_fg; - background: @tabbar_bg; - border: none; - border-right: 1px solid @tabbar_border; - padding: 2px; -} - -QTabBar::tab:selected { - color: @tabbar_selected_fg; - background: @tabbar_selected_bg; - border: none; - border-right: 1px solid @tabbar_border; -} - -QTabBar::tab:hover { - color: @tabbar_hover_fg; - background: @tabbar_hover_bg; - border: none; - border-right: 1px solid @tabbar_border; -} - -QTabBar::close-button { - image: url(close_grey.svg); -} - -QTabBar::close-button:hover { - image: url(close.svg); - background-color: @tabbar_closebutton_hover_bg; -} - -QTabBar::close-button:focus { - image: url(close.svg); - background-color: @tabbar_closebutton_focus_bg; -} - -QTabBar::scroller { - width: 20px; -} - -QTabBar QToolButton { - border: none; -} - -QTabBar QToolButton::right-arrow:enabled { - image: url(right.svg); -} - -QTabBar QToolButton::left-arrow:enabled { - image: url(left.svg); -} - -QTabBar QToolButton::right-arrow:disabled { - image: url(right_disabled.svg); -} - -QTabBar QToolButton::left-arrow:disabled { - image: url(left_disabled.svg); -} -/* End QTabBar */ - -VSelectorItemWidget QLabel[SelectorItemShortcutLabel="true"] { - font: bold; - border: 2px solid @selectoritem_border; - padding: 3px; - border-radius: 5px; - background-color: @selectoritem_bg; - color: @selectoritem_fg; -} - -VInsertSelector { - border: none; - background: @insertselector_bg; -} - -/* QTreeView */ -QTreeView { - color: @treeview_fg; - background: @treeview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QTreeView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QTreeView[ItemBorder="true"]::item { - padding-top: 5px; - padding-bottom: 5px; - border-bottom: 1px solid @treeview_item_border_bg; -} - -QTreeView::item:hover { - color: @treeview_item_hover_fg; - background: @treeview_item_hover_bg; -} - -QTreeView::item:selected { - color: @treeview_item_selected_fg; - background: @treeview_item_selected_bg; -} - -QTreeView::item:selected:active { - color: @treeview_item_selected_active_fg; - background: @treeview_item_selected_active_bg; -} - -QTreeView::item:selected:!active { - color: @treeview_item_selected_inactive_fg; - background: @treeview_item_selected_inactive_bg; -} - -QTreeView::branch:has-siblings:!adjoins-item { - border-image: url(line.svg) 0; -} - -QTreeView::branch:has-siblings:adjoins-item { - border-image: url(branch_more.svg) 0; -} - -QTreeView::branch:!has-children:!has-siblings:adjoins-item { - border-image: url(branch_end.svg) 0; -} - -QTreeView::branch:has-children:!has-siblings:closed, -QTreeView::branch:closed:has-children:has-siblings { - border-image: none; - image: url(branch_closed.svg); -} - -QTreeView::branch:open:has-children:!has-siblings, -QTreeView::branch:open:has-children:has-siblings { - border-image: none; - image: url(branch_open.svg); -} - -QTreeView[PlainTree="true"]::branch:has-siblings:!adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:has-siblings:adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:!has-children:!has-siblings:adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:has-children:!has-siblings:closed, -QTreeView[PlainTree="true"]::branch:closed:has-children:has-siblings { - border-image: none; - image: none; -} - -QTreeView[PlainTree="true"]::branch:open:has-children:!has-siblings, -QTreeView[PlainTree="true"]::branch:open:has-children:has-siblings { - border-image: none; - image: none; -} -/* End QTreeView */ - -/* QListView */ -QListView { - color: @listview_fg; - background: @listview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QListView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QListView::item:hover { - color: @listview_item_hover_fg; - background: @listview_item_hover_bg; -} - -QListView::item:selected { - color: @listview_item_selected_fg; - background: @listview_item_selected_bg; -} - -QListView::item:selected:active { - color: @listview_item_selected_active_fg; - background: @listview_item_selected_active_bg; -} - -QListView::item:selected:!active { - color: @listview_item_selected_inactive_fg; - background: @listview_item_selected_inactive_bg; -} -/* End QListView */ - -/* QSplitter */ -QSplitter { - border: none; -} - -QSplitter::handle { - background-color: @splitter_handle_bg; -} - -QSplitter::handle:vertical { - height: 2px; -} - -QSplitter::handle:horizontal { - width: 2px; -} -/* End QSplitter */ - -/* QStatusBar */ -QStatusBar { - color: @statusbar_fg; - background: @statusbar_bg; -} -/* End QStatusBar */ - -QWidget[MainEditor="true"] { - border: none; -} - -QDialog { - color: @base_fg; - background: @base_bg; -} - -/* QScrollBar */ -QScrollBar::sub-page, QScrollBar::add-page { - background: transparent; -} - -QScrollBar:vertical { - background: @scrollbar_bg; - width: 16px; - margin: 16px 0px 16px 0px; - padding: 0px 2px 0px 2px; - border: none; -} - -QScrollBar::handle:vertical { - background: @scrollbar_handle_bg; - min-height: 16px; -} - -QScrollBar::handle:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:vertical { - border: none; - background: @scrollbar_bg; - width: 16px; - height: 16px; - subcontrol-position: bottom; - subcontrol-origin: margin; -} - -QScrollBar::add-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:vertical { - border: none; - background: @scrollbar_bg; - width: 16px; - height: 16px; - subcontrol-position: top; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::down-arrow:vertical { - image: url(down.svg); - width: 16px; - height: 16px; -} - -QScrollBar::up-arrow:vertical { - image: url(up.svg); - width: 16px; - height: 16px; -} - -QScrollBar:horizontal { - background: @scrollbar_bg; - height: 16px; - margin: 0px 16px 0px 16px; - padding: 2px 0px 2px 0px; - border: none; -} - -QScrollBar::handle:horizontal { - background: @scrollbar_handle_bg; - min-width: 16px; -} - -QScrollBar::handle:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:horizontal { - border: none; - background: @scrollbar_bg; - width: 16px; - height: 16px; - subcontrol-position: right; - subcontrol-origin: margin; -} - -QScrollBar::add-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:horizontal { - border: none; - background: @scrollbar_bg; - width: 16px; - height: 16px; - subcontrol-position: left; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::right-arrow:horizontal { - image: url(right.svg); - width: 16px; - height: 16px; -} - -QScrollBar::left-arrow:horizontal { - image: url(left.svg); - width: 16px; - height: 16px; -} -/* End QScrollBar */ - -/* QCheckBox */ -QCheckBox { - spacing: 5px; -} - -QCheckBox::indicator { - width: 20px; - height: 20px; -} - -QCheckBox::indicator:unchecked { - image: url(checkbox_unchecked.svg); -} - -QCheckBox::indicator:unchecked:hover { - background: @checkbox_indicator_hover_bg; -} - -QCheckBox::indicator:unchecked:pressed { - background: @checkbox_indicator_pressed_bg; -} - -QCheckBox::indicator:checked { - image: url(checkbox_checked.svg); -} - -QCheckBox::indicator:checked:hover { - background: @checkbox_indicator_hover_bg; -} - -QCheckBox::indicator:checked:pressed { - background: @checkbox_indicator_pressed_bg; -} - -QCheckBox::indicator:indeterminate:hover { - background: @checkbox_indicator_hover_bg; -} - -QCheckBox::indicator:indeterminate:pressed { - background: @checkbox_indicator_pressed_bg; -} -/* End QCheckBox */ - -/* QRadioButton */ -QRadioButton { - spacing: 5px; -} - -QRadioButton::indicator { - width: 20px; - height: 20px; -} - -QRadioButton::indicator:unchecked { - image: url(radiobutton_unchecked.svg); -} - -QRadioButton::indicator:unchecked:hover { - background: @radiobutton_indicator_hover_bg; -} - -QRadioButton::indicator:unchecked:pressed { - background: @radiobutton_indicator_pressed_bg; -} - -QRadioButton::indicator:checked { - image: url(radiobutton_checked.svg); -} - -QRadioButton::indicator:checked:hover { - background: @radiobutton_indicator_hover_bg; -} - -QRadioButton::indicator:checked:pressed { - background: @radiobutton_indicator_pressed_bg; -} -/* End QRadioButton */ - -/* QSpinBox */ -QSpinBox, QDoubleSpinBox { - border: 1px solid @spinbox_border; - color: @spinbox_fg; - background: @spinbox_bg; - padding-right: 25px; - min-height: 25px; -} - -QSpinBox::up-button, QDoubleSpinBox::up-button { - subcontrol-origin: border; - subcontrol-position: top right; /* position at the top right corner */ - width: 25px; - border: none; - background: transparent; -} - -QSpinBox::up-button:hover, QDoubleSpinBox::up-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::up-button:pressed, QDoubleSpinBox::up-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::up-arrow, QDoubleSpinBox::up-arrow { - image: url(up.svg); - width: 12px; - height: 12px; -} - -QSpinBox::up-arrow:disabled, QSpinBox::up-arrow:off, QDoubleSpinBox::up-arrow:disabled, QDoubleSpinBox::up-arrow:off { - image: url(up_disabled.svg); -} - -QSpinBox::down-button, QDoubleSpinBox::down-button { - subcontrol-origin: border; - subcontrol-position: bottom right; /* position at the top right corner */ - width: 25px; - border: none; - background: transparent; -} - -QSpinBox::down-button:hover, QDoubleSpinBox::down-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::down-button:pressed, QDoubleSpinBox::down-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::down-arrow, QDoubleSpinBox::down-arrow { - image: url(down.svg); - width: 12px; - height: 12px; -} - -QSpinBox::down-arrow:disabled, QSpinBox::down-arrow:off, QDoubleSpinBox::down-arrow:disabled, QDoubleSpinBox::down-arrow:off { - image: url(down_disabled.svg); -} -/* End QSpinBox */ - -/* QHeaderView */ -QHeaderView::section { - background: @headerview_bg; - color: @headerview_fg; - padding-left: 4px; - border: none; - border-left: 1px solid @headerview_border; - border-bottom: 1px solid @headerview_border; -} - -QHeaderView::section:checked -{ - color: @headerview_checked_fg; - background: @headerview_checked_bg; -} - -/* style the sort indicator */ -QHeaderView::down-arrow { - image: url(down.svg); -} - -QHeaderView::up-arrow { - image: url(up.svg); -} -/* End QHeaderView */ - -QWidget#FindReplaceTitleWidget { - background: @title_bg; -} - -QAbstractScrollArea::corner { - background: @scrollbar_bg; - border: none; -} diff --git a/src/resources/themes/v_white/v_white_codeblock.css b/src/resources/themes/v_white/v_white_codeblock.css deleted file mode 100644 index fdf954d5..00000000 --- a/src/resources/themes/v_white/v_white_codeblock.css +++ /dev/null @@ -1,99 +0,0 @@ -/* - -Original highlight.js style (c) Ivan Sagalaev - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #E0E0E0; -} - - -/* Base color: saturation 0; */ - -.hljs, -.hljs-subst { - color: #363636; -} - -.hljs-comment { - color: #767676; -} - -.hljs-keyword, -.hljs-attribute, -.hljs-selector-tag, -.hljs-meta-keyword, -.hljs-doctag, -.hljs-name { - color: #0000ee; -} - - -/* User color: hue: 0 */ - -.hljs-type, -.hljs-string, -.hljs-number, -.hljs-selector-id, -.hljs-selector-class, -.hljs-quote, -.hljs-template-tag, -.hljs-deletion { - color: #880000; -} - -.hljs-title, -.hljs-section { - color: #880000; - font-weight: bold; -} - -.hljs-regexp, -.hljs-symbol, -.hljs-variable, -.hljs-template-variable, -.hljs-link, -.hljs-selector-attr, -.hljs-selector-pseudo { - color: #BC6060; -} - - -/* Language color: hue: 90; */ - -.hljs-literal { - color: #af00d7; -} - -.hljs-built_in, -.hljs-bullet, -.hljs-code, -.hljs-addition { - color: #008700; -} - - -/* Meta color: hue: 200 */ - -.hljs-meta { - color: #1f7199; -} - -.hljs-meta-string { - color: #4d99bf; -} - - -/* Misc effects */ - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/src/resources/vnote.ini b/src/resources/vnote.ini deleted file mode 100644 index e066da74..00000000 --- a/src/resources/vnote.ini +++ /dev/null @@ -1,294 +0,0 @@ -[global] -; Theme name -theme=v_pure - -welcome_page_path=:/resources/welcome.html - -; CSS style name for Markdown template -; Empty to use theme's css style -css_style= - -; Code block CSS style for Markdown template -; Empty to use theme's css style -code_block_css_style= - -; Editor style name -; Empty to use theme's editor style -editor_style= - -current_notebook=0 -tab_stop_width=4 -is_expand_tab=true -highlight_cursor_line=true -highlight_selected_word=true -highlight_searched_word=true -auto_indent=true -auto_list=true -current_background_color=System -current_render_background_color=System -language=System - -; 0 - Hoedown, 1 - Marked, 2 - Markdown-it, 3 - Showdown -markdown_converter=2 - -enable_mermaid=false -enable_mathjax=false - -; Enable flowchart.js -enable_flowchart=false - -; -1 - calculate the factor -web_zoom_factor=-1 - -; Syntax highlight within code blocks in edit mode -enable_code_block_highlight=true - -; Enable image preview in edit mode -enable_preview_images=true - -; Enable image preview constraint in edit mode to constrain the widht of the preview -enable_preview_image_constraint=true - -; Enable image constraint in read mode to constrain the width of the image -enable_image_constraint=true - -; Center image and add the alt text as caption -enable_image_caption=false - -; Image folder name for the notes -image_folder=_v_images - -; Image folder name for the external files -external_image_folder=_v_images - -; Attachment folder name for the notes -attachment_folder=_v_attachments - -; Enable trailing space highlight -enable_trailing_space_highlight=true - -; Enable Vim mode in edit mode -enable_vim_mode=false - -; Enable smart input method in Vim mode (disable IM in non-Insert modes) -enable_smart_im_in_vim_mode=true - -; Display an area besides the editor area to show line number -; 0 - None, 1 - Absolute, 2 - Relative, 3 - CodeBlock -editor_line_number=0 - -; Whether minimize to system tray when closing the app -; -1: uninitialized, prompt user for the behavior -; 0: do not minimize to system tray -; 1: minimize to system tray -minimize_to_system_tray=-1 - -; Suffixes list of Markdown files separated by : -; Case-insensitive -markdown_suffix=md:markdown:mkd - -; Markdown highlight timer interval (milliseconds) -markdown_highlight_interval=400 - -; Adds specified height between lines (in pixels) -line_distance_height=3 - -; Whether insert the note name as a title when creating a new note -insert_title_from_note_name=true - -; Default open mode when opening a note -; 0 - Read, 1 - Edit -note_open_mode=0 - -; Whether auto generate heading sequence -; 0 - Disabled, 1 - Enabled, 2 - Enabled only for notes -heading_sequence_type=0 - -; Heading sequence base level -heading_sequence_base_level=1 - -; Style the xth column in fenced code block -; 0 - no color column -color_column=0 - -; Whether display line number of code block in read mode -enable_code_block_line_number=false - -; The icon size of tool bar (in pixels) -tool_bar_icon_size=18 - -; Markdown-it options -; Enable HTML tags in source -markdownit_opt_html=true -; Convert '\n' in paragraphs into
    -markdownit_opt_breaks=false -; Auto-convert URL-like text to links -markdownit_opt_linkify=true - -; Default name of the recycle bin of notebook -recycle_bin_folder=_v_recycle_bin - -; Default name of the recycle bin of external files -external_recycle_bin_folder=_v_recycle_bin - -; Confirm before deleting unused images -confirm_images_clean_up=true - -; Confirm before reloading folder from disk -confirm_reload_folder=true - -; Whether double click on a tab to close it -double_click_close_tab=true - -; Whether put folder and note panel in one vertical column -enable_compact_mode=true - -; Whether enable tools dock widget -tools_dock_checked=true - -; Pages to open on startup -; 0 - none; 1 - Continue where you left off; 2 - specific pages -startup_page_type=0 - -; Specific pages to open on startup when startup_page_type is 2 -; A list of file path separated by , -; Notice: should escape \ by \\ -; C:\users\vnote\vnote.md -> C:\\users\\vnote\\vnote.md -startup_pages= - -; Timer interval to check file modification or save file to tmp file in milliseconds -file_timer_interval=2000 - -; Directory for the backup file -; A directory "." means to put the backup file in the same directory as the edited file -backup_directory=. - -; String which is appended to a file name to make the name of the backup file -backup_extension=.vswp - -; Enable backup file -enable_backup_file=true - -; Skipped keys in Vim mode -; c: Ctrl+C -; v: Ctrl+V -vim_exemption_keys=cv - -; Path of the flash page, related to the configuration folder -; Could be absolute path -flash_page=flash_page.md - -[web] -; Location and configuration for Mathjax -mathjax_javascript=https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML - -[predefined_colors] -1\name=White -1\rgb=EEEEEE -2\name=Green -2\rgb=CCE8CF -3\name=Wheat2 -3\rgb=DFC7B2 -4\name=LightGrey -4\rgb=D3D3D3 -size=4 - -[shortcuts] -; Define shortcuts here, with each item in the form "operation=keysequence". -; Leave keysequence empty to disable the shortcut of an operation. -; Custom shortcuts may conflict with some key bindings in edit mode or Vim mode. -; Ctrl+Q is reserved for quitting VNote. - -; Leader key of Captain mode -CaptainMode=Ctrl+E -; Create a note in current folder -NewNote=Ctrl+Alt+N -; Save current note -SaveNote=Ctrl+S -; Save changes and enter read mode -SaveAndRead=Ctrl+T -; Edit current note -EditNote=Ctrl+W -; Close current note -CloseNote= -; Open file/replace dialog -Find=Ctrl+F -; Find next occurence -FindNext=F3 -; Find previous occurence -FindPrevious=Shift+F3 -; Recover last closed file -LastClosedFile=Ctrl+Shift+T -; Activate next tab -ActivateNextTab=Ctrl+Tab -; Activate previous tab -ActivatePreviousTab=Ctrl+Shift+Tab -; Activate flash page -FlashPage=Ctrl+Alt+L - -[captain_mode_shortcuts] -; Define shortcuts in Captain mode here. -; There shortcuts are the sub-sequence after the CaptainMode key sequence -; in [shortcuts]. - -; Enter Navigation mode -NavigationMode=W -; Show attachment list of current note -AttachmentList=A -; Locate to the folder of current note -LocateCurrentFile=D -; Toggle Expand mode -ExpandMode=E -; Alternate one/two panels view -OnePanelView=P -; Discard changes and enter read mode -DiscardAndRead=Q -; Toggle Tools dock widget -ToolsDock=T -; Close current note -CloseNote=X -; Show shortcuts help document -ShortcutsHelp=? -; Flush the log file -FlushLogFile=";" -; Show opened files list -OpenedFileList=F -; Activate the ith tab -ActivateTab1=1 -ActivateTab2=2 -ActivateTab3=3 -ActivateTab4=4 -ActivateTab5=5 -ActivateTab6=6 -ActivateTab7=7 -ActivateTab8=8 -ActivateTab9=9 -; Alternate between current and last tab -AlternateTab=0 -; Activate next tab -ActivateNextTab=J -; Activate previous tab -ActivatePreviousTab=K -; Activate the window split on the left -ActivateSplitLeft=H -; Activate the window split on the right -ActivateSplitRight=L -; Move current tab one split left -MoveTabSplitLeft=Shift+H -; Move current tab one split right -MoveTabSplitRight=Shift+L -; Create a vertical split -VerticalSplit=V -; Remove current split -RemoveSplit=R -; Evaluate selected text or cursor word as magic words -MagicWord=M -; Prompt for user to apply a snippet -ApplySnippet=S - -[external_editors] -; Define external editors which could be called to edit notes -; One program per line with the format name="program %0 arg1 arg2" -; in which %0 will be replaced with the note file path -; Need to escape \ and ", use double quotes to quote paths/arguments with spaces -; SHOULD defined in user config file, not here diff --git a/src/resources/welcome.html b/src/resources/welcome.html deleted file mode 100644 index ea85947f..00000000 --- a/src/resources/welcome.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - Welcome VNote - - -

    Welcome to VNote

    -

    A Vim-Like Note for Markdown

    -

    Under development by Le Tan. -Please contact tamlokveer@gmail.com if you have any questions. -

    - - diff --git a/src/src.pro b/src/src.pro deleted file mode 100644 index 1996e1fb..00000000 --- a/src/src.pro +++ /dev/null @@ -1,268 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2016-10-01T11:03:59 -# -#------------------------------------------------- - -QT += core gui webenginewidgets webchannel network svg printsupport - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = VNote -TEMPLATE = app - -RC_ICONS = resources/icons/vnote.ico -ICON = resources/icons/vnote.icns - -TRANSLATIONS += translations/vnote_zh_CN.ts - -SOURCES += main.cpp\ - vmainwindow.cpp \ - vdirectorytree.cpp \ - vnote.cpp \ - vnotebook.cpp \ - dialog/vnewdirdialog.cpp \ - vconfigmanager.cpp \ - vfilelist.cpp \ - dialog/vnewfiledialog.cpp \ - vedit.cpp \ - vdocument.cpp \ - utils/vutils.cpp \ - vpreviewpage.cpp \ - hgmarkdownhighlighter.cpp \ - vstyleparser.cpp \ - dialog/vnewnotebookdialog.cpp \ - vmarkdownconverter.cpp \ - dialog/vnotebookinfodialog.cpp \ - dialog/vdirinfodialog.cpp \ - dialog/vfileinfodialog.cpp \ - veditoperations.cpp \ - vmdeditoperations.cpp \ - dialog/vinsertimagedialog.cpp \ - vdownloader.cpp \ - veditarea.cpp \ - veditwindow.cpp \ - vedittab.cpp \ - voutline.cpp \ - vsingleinstanceguard.cpp \ - vdirectory.cpp \ - vfile.cpp \ - vnotebookselector.cpp \ - vnofocusitemdelegate.cpp \ - vavatar.cpp \ - vmdedit.cpp \ - dialog/vfindreplacedialog.cpp \ - dialog/vsettingsdialog.cpp \ - dialog/vdeletenotebookdialog.cpp \ - dialog/vselectdialog.cpp \ - vcaptain.cpp \ - vopenedlistmenu.cpp \ - vnavigationmode.cpp \ - vorphanfile.cpp \ - vcodeblockhighlighthelper.cpp \ - vwebview.cpp \ - vexporter.cpp \ - vmdtab.cpp \ - vhtmltab.cpp \ - utils/vvim.cpp \ - utils/veditutils.cpp \ - vvimindicator.cpp \ - vbuttonwithwidget.cpp \ - vtabindicator.cpp \ - dialog/vupdater.cpp \ - dialog/vorphanfileinfodialog.cpp \ - vtextblockdata.cpp \ - utils/vpreviewutils.cpp \ - dialog/vconfirmdeletiondialog.cpp \ - vnotefile.cpp \ - vattachmentlist.cpp \ - dialog/vsortdialog.cpp \ - vfilesessioninfo.cpp \ - vtableofcontent.cpp \ - utils/vmetawordmanager.cpp \ - vlineedit.cpp \ - dialog/vinsertlinkdialog.cpp \ - vplaintextedit.cpp \ - vimageresourcemanager.cpp \ - vlinenumberarea.cpp \ - veditor.cpp \ - vmdeditor.cpp \ - veditconfig.cpp \ - vpreviewmanager.cpp \ - vimageresourcemanager2.cpp \ - vtextdocumentlayout.cpp \ - vtextedit.cpp \ - vsnippetlist.cpp \ - vsnippet.cpp \ - dialog/veditsnippetdialog.cpp \ - utils/vimnavigationforwidget.cpp \ - vtoolbox.cpp \ - vinsertselector.cpp \ - utils/vclipboardutils.cpp \ - vpalette.cpp \ - vbuttonmenuitem.cpp \ - utils/viconutils.cpp \ - lineeditdelegate.cpp - -HEADERS += vmainwindow.h \ - vdirectorytree.h \ - vnote.h \ - vnotebook.h \ - dialog/vnewdirdialog.h \ - vconfigmanager.h \ - vfilelist.h \ - dialog/vnewfiledialog.h \ - vedit.h \ - vconstants.h \ - vdocument.h \ - utils/vutils.h \ - vpreviewpage.h \ - hgmarkdownhighlighter.h \ - vstyleparser.h \ - dialog/vnewnotebookdialog.h \ - vmarkdownconverter.h \ - dialog/vnotebookinfodialog.h \ - dialog/vdirinfodialog.h \ - dialog/vfileinfodialog.h \ - veditoperations.h \ - vmdeditoperations.h \ - dialog/vinsertimagedialog.h \ - vdownloader.h \ - veditarea.h \ - veditwindow.h \ - vedittab.h \ - voutline.h \ - vsingleinstanceguard.h \ - vdirectory.h \ - vfile.h \ - vnotebookselector.h \ - vnofocusitemdelegate.h \ - vavatar.h \ - vmdedit.h \ - dialog/vfindreplacedialog.h \ - dialog/vsettingsdialog.h \ - dialog/vdeletenotebookdialog.h \ - dialog/vselectdialog.h \ - vcaptain.h \ - vopenedlistmenu.h \ - vnavigationmode.h \ - vorphanfile.h \ - vcodeblockhighlighthelper.h \ - vwebview.h \ - vexporter.h \ - vmdtab.h \ - vhtmltab.h \ - utils/vvim.h \ - utils/veditutils.h \ - vvimindicator.h \ - vbuttonwithwidget.h \ - vedittabinfo.h \ - vtabindicator.h \ - dialog/vupdater.h \ - dialog/vorphanfileinfodialog.h \ - vtextblockdata.h \ - utils/vpreviewutils.h \ - dialog/vconfirmdeletiondialog.h \ - vnotefile.h \ - vattachmentlist.h \ - dialog/vsortdialog.h \ - vfilesessioninfo.h \ - vtableofcontent.h \ - utils/vmetawordmanager.h \ - vlineedit.h \ - dialog/vinsertlinkdialog.h \ - vplaintextedit.h \ - vimageresourcemanager.h \ - vlinenumberarea.h \ - veditor.h \ - vmdeditor.h \ - veditconfig.h \ - vpreviewmanager.h \ - vimageresourcemanager2.h \ - vtextdocumentlayout.h \ - vtextedit.h \ - vsnippetlist.h \ - vsnippet.h \ - dialog/veditsnippetdialog.h \ - utils/vimnavigationforwidget.h \ - vtoolbox.h \ - vinsertselector.h \ - utils/vclipboardutils.h \ - vpalette.h \ - vbuttonmenuitem.h \ - utils/viconutils.h \ - lineeditdelegate.h - -RESOURCES += \ - vnote.qrc \ - translations.qrc - -OTHER_FILES += \ - utils/highlightjs/highlight.pack.js \ - utils/markdown-it/markdown-it-headinganchor.js \ - utils/markdown-it/markdown-it-task-lists.min.js \ - utils/markdown-it/markdown-it.min.js \ - utils/marked/marked.min.js \ - utils/mermaid/mermaidAPI.min.js - -macx { - LIBS += -L/usr/local/lib - INCLUDEPATH += /usr/local/include -} - -win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../hoedown/release/ -lhoedown -else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../hoedown/debug/ -lhoedown -else:unix: LIBS += -L$$OUT_PWD/../hoedown/ -lhoedown - -INCLUDEPATH += $$PWD/../hoedown -DEPENDPATH += $$PWD/../hoedown - -win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../peg-highlight/release/ -lpeg-highlight -else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../peg-highlight/debug/ -lpeg-highlight -else:unix: LIBS += -L$$OUT_PWD/../peg-highlight/ -lpeg-highlight - -INCLUDEPATH += $$PWD/../peg-highlight -DEPENDPATH += $$PWD/../peg-highlight - -win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../peg-highlight/release/libpeg-highlight.a -else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../peg-highlight/debug/libpeg-highlight.a -else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../peg-highlight/release/peg-highlight.lib -else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../peg-highlight/debug/peg-highlight.lib -else:unix: PRE_TARGETDEPS += $$OUT_PWD/../peg-highlight/libpeg-highlight.a - -## INSTALLS -unix:!macx { - isEmpty(PREFIX): PREFIX = /usr - DATADIR = $${PREFIX}/share - - # install desktop file - desktop.path = $${DATADIR}/applications - desktop.files += vnote.desktop - - # install icons - icon16.path = $${DATADIR}/icons/hicolor/16x16/apps - icon16.files = resources/icons/16x16/vnote.png - - icon32.path = $${DATADIR}/icons/hicolor/32x32/apps - icon32.files = resources/icons/32x32/vnote.png - - icon48.path = $${DATADIR}/icons/hicolor/48x48/apps - icon48.files = resources/icons/48x48/vnote.png - - icon64.path = $${DATADIR}/icons/hicolor/64x64/apps - icon64.files = resources/icons/64x64/vnote.png - - icon128.path = $${DATADIR}/icons/hicolor/128x128/apps - icon128.files = resources/icons/128x128/vnote.png - - icon256.path = $${DATADIR}/icons/hicolor/256x256/apps - icon256.files = resources/icons/256x256/vnote.png - - iconsvg.path = $${DATADIR}/icons/hicolor/scalable/apps - iconsvg.files = resources/icons/vnote.svg - - target.path = $${PREFIX}/bin - - INSTALLS += target desktop icon16 icon32 icon48 icon64 icon128 icon256 iconsvg - message("VNote will be installed in prefix $${PREFIX}") -} diff --git a/src/translations.qrc b/src/translations.qrc deleted file mode 100644 index 1effdca7..00000000 --- a/src/translations.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - translations/vnote_zh_CN.qm - - diff --git a/src/translations/vnote_zh_CN.qm b/src/translations/vnote_zh_CN.qm deleted file mode 100644 index 6f996bbc..00000000 Binary files a/src/translations/vnote_zh_CN.qm and /dev/null differ diff --git a/src/translations/vnote_zh_CN.ts b/src/translations/vnote_zh_CN.ts deleted file mode 100644 index 8e698601..00000000 --- a/src/translations/vnote_zh_CN.ts +++ /dev/null @@ -1,4611 +0,0 @@ - - - - - QObject - - - All magic words: - 所有幻词: - - - - Insert Link - 插入链接 - - - - Found no match - 没有找到匹配项 - - - - Found %1 %2 - 找到 %1 %2 - - - - matches - 处匹配 - - - - match - 处匹配 - - - - Replace %1 %2 - 替换了 %1 %2 - - - - occurences - 处匹配 - - - - occurence - 处匹配 - - - - PlainText - 纯文本 - - - - Html - Html - - - - Invalid - 无效 - - - - VAttachmentList - - - Add - 添加 - - - - Clear - 清空 - - - - - - - - - Warning - 警告 - - - - Are you sure to clear attachments of note <span style="%1">%2</span>? - 确认删除笔记 <span style="%1">%2</span> 的所有附件? - - - - <span style="%1">WARNING</span>: VNote will delete all the files in directory <span style="%2">%3</span>.Deleted files could be found in the recycle bin of this note.<br>The operation is IRREVERSIBLE! - <span style="%1">警告</span>:VNote会删除位于目录 <span style="%2">%3</span> 中的所有文件。被删除的文件可以在该笔记的回收站中找回。<br>该操作是不可逆的! - - - - Fail to clear attachments of note <span style="%1">%2</span>. - 清空笔记 <span style="%1">%2</span> 的附件失败。 - - - - - - Please check the attachments folder and maintain the configuration file manually. - 请检查附件文件夹并手动维护配置文件。 - - - - Open Folder - 打开所在文件夹 - - - - &Open - 打开 (&O) - - - - Open current attachment file - 打开当前附件文件 - - - - &Delete - 删除 (&D) - - - - Delete selected attachments - 删除选定附件 - - - - &Sort - 排序 (&S) - - - - Sort attachments manually - 对附件进行手动排序 - - - - %1 %2 - %1 %2 - - - - Files - 文件 - - - - File - 文件 - - - - Select Files As Attachments - 选择文件作为附件 - - - - Fail to add attachment %1 for note <span style="%2">%3</span>. - 为笔记 <span style="%2">%3</span> 添加附件 %1 失败。 - - - - %1 %2 added as attachments - %1个%2添加为附件 - - - - files - 文件 - - - - file - 文件 - - - - Are you sure to delete these attachments of note <span style="%1">%2</span>? - 确认删除笔记 <span style="%1">%2</span> 的这些附件? - - - - Deleted files could be found in the recycle bin of this note.<br>Click "Cancel" to leave them untouched. - 被删除的文件可以在该笔记的回收站中找回。<br>点击“取消”以终止操作。 - - - - - Confirm Deleting Attachments - 确认删除附件 - - - - - Fail to delete attachments of note <span style="%1">%2</span>. - 删除笔记 <span style="%1">%2</span> 的附件失败。 - - - - Sort Attachments - 排序附件 - - - - Sort attachments of note <span style="%1">%2</span> in the configuration file. - 对笔记 <span style="%1">%2</span> 的附件在配置文件中进行排序。 - - - - Name - 名字 - - - - Fail to sort attachments of note <span style="%1">%2</span>. - 对笔记 <span style="%1">%2</span> 的附件的排序失败。 - - - - Rename Attachment - 重命名附件 - - - - Fail to rename attachment <span style="%1">%2</span>. - 重命名附件 <span style="%1">%2</span> 失败。 - - - - VNote detects that these attachments of note <span style="%1">%2</span> are missing in disk. Would you like to remove them from the note? - VNote无法在磁盘中找到笔记 <span style="%1">%2</span> 的这些附件。是否需要将这些附件从笔记中移除? - - - - Click "Cancel" to leave them untouched. - 点击“取消”以终止操作。 - - - - VCaptain - - - NavigationMode - 展览模式 - - - - VConfirmDeletionDialog - - - Do not ask for confirmation again - 不要再次询问 - - - - %1/%2 Items - %1/%2 项 - - - - VDeleteNotebookDialog - - - Are you sure to delete notebook <span style="%1">%2</span>? - 确认删除笔记本 <span style="%1">%2</span>? - - - - Delete files from disk - 从磁盘中删除文件 - - - - When checked, VNote will delete all files (including Recycle Bin) of this notebook from disk - 选中后,VNote会从磁盘中删除该笔记本内的所有文件(包括回收站) - - - - <span style="%1">WARNING</span>: VNote may delete <b>ANY</b> files in directory <span style="%2">%3</span> and directory <span style="%2">%4</span>!<br>VNote will try to delete all the root folders within this notebook one by one.<br>It may be UNRECOVERABLE! - <span style="%1">警告</span>:VNote可能会删除位于目录 <span style="%2">%3</span> 和 <span style="%2">%4</span> 中的<b>所有</b>文件!<br>VNote会尝试逐个删除该笔记本下的所有根文件夹。<br>该操作可能是不可恢复的! - - - - VNote won't delete files in directory <span style="%1">%2</span>. - VNote不会删除位于目录 <span style="%1">%2</span> 中的文件。 - - - - VDirInfoDialog - - - Folder &name: - 文件夹名 (&N): - - - - Created time: - 创建时间: - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写) <span style="%2">%3</span>。请选择另一个名字。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>:名字 <span style="%2">%3</span> 包含非法字符(解析幻词之后)。 - - - <span style="%1">WARNING</span>: Name (case-insensitive) already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写)。请选择另一个名字。 - - - - VDirectory - - - Fail to open folder %1. - 打开文件夹 %1 失败。 - - - - %1 already exists in directory %2. - %1 已经存在于目录 %2 中。 - - - - Fail to create folder in %1. - 在 %1 中新建文件夹失败。 - - - - - Fail to write configuration of folder %1. - 写入文件夹 %1 的配置失败。 - - - - Fail to delete the directory %1. - 删除目录 %1 失败。 - - - - Fail to remove the folder from the folder configuration. - 从文件夹配置中移除文件夹失败。 - - - - Fail to open target folder. - 打开目标文件夹失败。 - - - - cut - 剪切 - - - - copy - 复制 - - - - Fail to %1 the folder. - %1文件夹失败。 - - - - Fail to add the folder to target folder's configuration. - 将该文件夹添加到目标文件夹的配置失败。 - - - - VDirectoryTree - - - &Delete - 删除 (&D) - - - - New &Root Folder - 新建根文件夹 (&R) - - - - &New Subfolder - 新建子文件夹 (&N) - - - - Delete selected folder - 删除选定文件夹 - - - - &Info %1 - 信息 (&I) %1 - - - - View and edit current folder's information - 查看并编辑当前文件夹的信息 - - - - &Copy %1 - 复制 (&C) %1 - - - - Copy selected folders - 复制选定文件夹 - - - - C&ut %1 - 剪切 (&U) %1 - - - - Cut selected folders - 剪切选定文件夹 - - - - &Paste %1 - 粘贴 (&P) %1 - - - - Paste folders in this folder - 在当前文件夹中粘贴所复制的文件夹 - - - - &Open Folder Location - 打开文件夹所在位置 (&O) - - - - Open the folder containing this folder in operating system - 在操作系统中打开该文件夹所在目录 - - - - &Reload From Disk - 从磁盘中重新加载 (&R) - - - - Reload the content of this folder (or notebook) from disk - 从磁盘中重新加载该文件夹(或笔记本)的内容 - - - - &Sort - 排序 (&S) - - - - Sort folders in this folder/notebook manually - 对该文件夹或笔记本中的文件夹进行手动排序 - - - - - - - - - - - - - - Warning - 警告 - - - - - Fail to open notebook <span style="%1">%2</span>. - 打开笔记本 <span style="%1">%2</span> 失败。 - - - - Please check if the notebook's root folder <span style="%1">%2</span> exists. - 请检查该笔记本的根文件夹 <span style="%1">%2</span> 是否存在。 - - - - Fail to open folder <span style="%1">%2</span>. - 打开文件夹 <span style="%1">%2</span> 失败。 - - - - Please check if directory <span style="%1">%2</span> exists. - 请检查目录 <span style="%1">%2</span> 是否存在。 - - - - Create a subfolder in <span style="%1">%2</span>. - 在文件夹 <span style="%1">%2</span> 中新建子文件夹。 - - - - Fail to create subfolder <span style="%1">%2</span>. - 新建子文件夹 <span style="%1">%2</span> 失败。 - - - - Fail to create root folder <span style="%1">%2</span>. - 新建根文件夹 <span style="%1">%2</span> 失败。 - - - - <span style="%1">WARNING</span>: VNote will delete the whole directory <span style="%2">%3</span>.Deleted files could be found in the recycle bin of this folder.<br>The operation is IRREVERSIBLE! - <span style="%1">警告</span>:VNote会删除整个目录 <span style="%2">%3</span>。被删除的文件可以在该文件夹的回收站中找回。<br>该操作是不可逆的! - - - - %1 %2 pasted - 粘贴了%1个%2 - - - - Sort Folders - 排序文件夹 - - - - Sort folders in %1 <span style="%2">%3</span> in the configuration file. - 对%1 <span style="%2">%3</span> 的文件夹在配置文件中进行排序。 - - - - - notebook - 笔记本 - - - - Name - 名字 - - - - Created Time - 创建时间 - - - - Fail to sort folders in %1 <span style="%2">%3</span>. - 对%1 <span style="%2">%3</spacn> 的文件夹排序失败。 - - - - Create Folder - 新建文件夹 - - - - Create a root folder in notebook <span style="%1">%2</span>. - 在笔记本 <span style="%1">%2</span> 中新建根文件夹。 - - - - Create Root Folder - 新建根文件夹 - - - - Are you sure to delete folder <span style="%1">%2</span>? - 确认删除文件夹 <span style="%1">%2</span>? - - - - Fail to delete folder <span style="%1">%2</span>.<br>Please check <span style="%1">%3</span> and manually delete it. - 删除文件夹 <span style="%1">%2</span> 失败。<br>请检查 <span style="%1">%3</span> 并手动删除。 - - - - %1 %2 deleted - 删除了%1个%2 - - - - - - folders - 文件夹 - - - - - - - - folder - 文件夹 - - - - Folder Information - 文件夹信息 - - - - Fail to rename folder <span style="%1">%2</span>. - 重命名文件夹 <span style="%1">%2</span> 失败。 - - - - Are you sure to reload folder <span style="%1">%2</span>? - 确认重新加载文件夹 <span style="%1">%2</span>? - - - - Folder %1 reloaded from disk - 文件夹 %1 已从磁盘中重新加载 - - - - Are you sure to reload notebook <span style="%1">%2</span>? - 确认重新加载笔记本 <span style="%1">%2</span>? - - - - Notebook %1 reloaded from disk - 笔记本 %1 已从磁盘中重新加载 - - - - Information - 注意 - - - - VNote will close all the related notes before reload. - VNote会在重新加载前关闭所有相关笔记。 - - - - Please check if path <span style="%1">%2</span> exists. - 请检查路径 <span style="%1">%2</span> 是否存在。 - - - - %1 %2 %3 - %3了%1个%2 - - - - cut - 剪切 - - - - copied - 复制 - - - - Fail to paste folder <span style="%1">%2</span>. - 粘贴文件夹 <span style="%1">%2</span> 失败。 - - - - VNote could not find this folder in any notebook. - VNote无法在任何笔记本中找到该文件夹。 - - - - Fail to copy folder <span style="%1">%2</span>. - 复制文件夹 <span style="%1">%2</span> 失败。 - - - - Create a root folder in current notebook - 在当前笔记本中新建根文件夹 - - - - Create a subfolder - 新建子文件夹 - - - - VEdit - - - Insert Link - 插入链接 - - - - Found no match - 没有找到匹配项 - - - - Found %1 %2 - 找到 %1 %2 - - - - matches - 处匹配 - - - - match - 处匹配 - - - - Replace %1 %2 - 替换了 %1 %2 - - - - occurences - 处匹配 - - - - occurence - 处匹配 - - - - &Save Changes And Read - 保存更改并阅读 (&S) - - - - Save changes and exit edit mode - 保存对当前笔记的更改并退出编辑模式 - - - - &Discard Changes And Read - 放弃更改并阅读 (&D) - - - - Discard changes and exit edit mode - 放弃对当前笔记的更改并退出编辑模式 - - - - &Edit - 编辑 (&E) - - - - Edit current note - 编辑当前笔记 - - - - VEditArea - - - ActivateTab1 - 激活标签页1 - - - - ActivateTab2 - 激活标签页2 - - - - ActivateTab3 - 激活标签页3 - - - - ActivateTab4 - 激活标签页4 - - - - ActivateTab5 - 激活标签页5 - - - - ActivateTab6 - 激活标签页6 - - - - ActivateTab7 - 激活标签页7 - - - - ActivateTab8 - 激活标签页8 - - - - ActivateTab9 - 激活标签页9 - - - - AlternateTab - 轮换标签页 - - - - OpenedFileList - 已打开笔记列表 - - - - ActivateSplitLeft - 激活左分割 - - - - ActivateSplitRight - 激活右分割 - - - - MoveTabSplitLeft - 左移标签页一个分割窗口 - - - - MoveTabSplitRight - 右移标签页一个分割窗口 - - - - ActivateNextTab - 激活下一个标签页 - - - - ActivatePreviousTab - 激活上一个标签页 - - - - VerticalSplit - 垂直分割 - - - - RemoveSplit - 移除分割 - - - - MagicWord - 幻词 - - - - ApplySnippet - 应用片段 - - - - VEditSnippetDialog - - - None - - - - - String in the content to mark the cursor position - 在片段内容中用于表示光标位置的文本 - - - - String in the content to be replaced with selected text - 在片段内容中用于表示所选文本的文本 - - - - Auto indent - 自动缩进 - - - - Auto indent the content according to the first line - 按照第一行自动缩进片段内容 - - - - Snippet &name: - 片段名字 (&N): - - - - Snippet &type: - 片段类型 (&T): - - - - Shortc&ut: - 快捷键 (&U): - - - - Cursor &mark: - 光标标记 (&M): - - - - &Selection mark: - 选择标记 (&S): - - - - &Content: - 内容 (&C): - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写) <span style="%2">%3</span>。请选择另一个名字。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>:名字 <span style="%2">%3</span> 包含非法字符(解析幻词之后)。 - - - - <span style="%1">WARNING</span>: Cursor mark <span style="%2">%3</span> occurs more than once in the content (after magic word evaluation). Please choose another mark. - <span style="%1">警告</span>:光标标记 <span style="%2">%3</span> 在片段内容中出现了多次(解析幻词之后)。请选择另一个标记。 - - - - <span style="%1">WARNING</span>: Cursor mark <span style="%2">%3</span> conflicts with selection mark. Please choose another mark. - <span style="%1">警告</span>:光标标记 <span style="%2">%3</span> 和选择标记冲突。请选择另一个标记。 - - - - VEditTab - - - Information - 注意 - - - - Note <span style="%1">%2</span> has been modified by another program. - 笔记 <span style="%1">%2</span> 已经被另一个程序更改。 - - - - Do you want to reload it? - 是否重新载入? - - - - VEditWindow - - - Locate To Folder - 定位所在文件夹 - - - - Locate the folder of current note - 定位到当前笔记所在的文件夹 - - - - Move One Split Left - 左移一个分割窗口 - - - - Move current tab to the split on the left - 将当前标签页往左移动一个分割窗口 - - - - Move One Split Right - 右移一个分割窗口 - - - - Move current tab to the split on the right - 将当前标签页往右移动一个分割窗口 - - - - Close Tab - 关闭标签页 - - - - Close current note tab - 关闭当前标签页 - - - - Close Other Tabs - 关闭其他标签页 - - - - Close all other note tabs - 关闭其他所有标签页 - - - - Close Tabs To The Right - 关闭右侧标签页 - - - - Close all the note tabs to the right of current tab - 关闭当前标签页右侧所有标签页 - - - - Note Info - 笔记信息 - - - - View and edit information of the note - 查看并编辑笔记的信息 - - - - Open Note Location - 打开笔记所在位置 - - - - Open the folder containing this note in operating system - 在操作系统中打开该笔记所在目录 - - - - Reload From Disk - 从磁盘中重新加载 - - - - Reload the content of this note from disk - 从磁盘中重新加载该笔记的内容 - - - - &Recycle Bin - 回收站 (&R) - - - - Open the recycle bin of this note - 打开该笔记的回收站 - - - - Opened Notes List - 已打开笔记列表 - - - - Split - 分割 - - - - Split current window vertically - 垂直分割当前窗口 - - - - Remove split - 移除分割 - - - - Remove current split window - 移除当前分割窗口 - - - - Menu - 菜单 - - - - VExporter - - - Target &path: - 目标路径 (&P): - - - - &Browse - 浏览文件 (&B) - - - - Page layout: - 页面布局: - - - - &Settings - 设置 (&S) - - - - Open File Location - 打开文件所在位置 - - - - Export Note - 导出笔记 - - - - Portable Document Format (*.pdf) - 可移植文档格式 (*.pdf) - - - - WebPage, Complete (*.html) - 网页,全部 (*.html) - - - - Export As - 导出到文件 - - - - Portrait - 纵向 - - - - Landscape - 横向 - - - - Export note <span style="%1">%2</span> as %3. - 将笔记 <span style="%1">%2</span> 导出为%3。 - - - - Export As %1 - 导出为%1 - - - - Exporting %1 - 正在导出 %1 - - - - VFileInfoDialog - - - Will be assigned when adding attachments - 添加附件时分配 - - - - The folder to hold attachments of this note - 保存该笔记的附件的文件夹 - - - - Last modified time within VNote - 在VNote中的最近修改时间 - - - - Note &name: - 笔记名 (&N): - - - - Attachment folder: - 附件文件夹: - - - - Created time: - 创建时间: - - - - Modified time: - 修改时间: - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写) <span style="%2">%3</span>。请选择另一个名字。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>:名字 <span style="%2">%3</span> 包含非法字符(解析幻词之后)。 - - - <span style="%1">WARNING</span>: Name (case-insensitive) already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写)。请选择另一个名字。 - - - - <span style="%1">WARNING</span>: Changing type of the note is not supported. Please use the same suffix as the old one. - <span style="%1">警告</span>:不支持修改笔记的类型。请使用原来的后缀名。 - - - - VFileList - - - &New Note - 新建笔记 (&N) - - - - &New Note %1 - 新建笔记 (&N) %1 - - - - &Open In Read Mode - 以阅读模式打开 (&O) - - - - Open current note in read mode - 以阅读模式打开当前笔记 - - - - Open In &Edit Mode - 以编辑模式打开 (&E) - - - - Open current note in edit mode - 以编辑模式打开当前笔记 - - - Open Via External Program - 调用外部程序打开 - - - Open current note via external program - 调用外部程序打开当前笔记 - - - - &Delete - 删除 (&D) - - - - Delete selected note - 删除选定笔记 - - - - &Sort - 排序 (&S) - - - - Sort notes in this folder manually - 对该文件夹中的笔记进行手动排序 - - - - Are you sure to delete these notes? - 确认删除这些笔记? - - - - <span style="%1">WARNING</span>: VNote will delete notes as well as all their images and attachments managed by VNote. Deleted files could be found in the recycle bin of these notes.<br>Click "Cancel" to leave them untouched.<br>The operation is IRREVERSIBLE! - <span style="%1">警告</span>:VNote会删除这些笔记以及这些笔记所有由VNote管理的图片和附件。被删除的文件可以在这些笔记的回收站中找回。<br>点击“取消”终止操作。<br>该操作是不可逆的! - - - - Confirm Deleting Notes - 确认删除笔记 - - - - Fail to delete note <span style="%1">%2</span>.<br>Please check <span style="%1">%3</span> and manually delete it. - 删除笔记 <span style="%1">%2</span> 失败。<br>请检查 <span style="%1">%3</span> 并手动删除。 - - - - %1 %2 deleted - 删除了%1个%2 - - - - - - notes - 笔记 - - - - - - note - 笔记 - - - - Skip importing non-exist file %1. - 跳过导入不存在的文件 %1。 - - - - Fail to copy file %1 as %2. - 复制文件 %1 为 %2 失败。 - - - - Fail to add the note %1 to target folder's configuration. - 将该笔记 %1 添加到目标文件夹的配置失败。 - - - - %1 %2 %3 - %3了%1个%2 - - - - cut - 剪切 - - - - copied - 复制 - - - - Fail to paste note <span style="%1">%2</span>. - 粘贴笔记 <span style="%1">%2</span> 失败。 - - - - VNote could not find this note in any notebook. - VNote无法在任何笔记本中找到该笔记。 - - - - VNote does not allow copy and paste notes with internal images in the same folder. - VNote不允许在同一个文件夹中复制并粘贴带有内部图片的笔记。 - - - - %1 %2 pasted - 粘贴了%1个%2 - - - - Sort Notes - 排序笔记 - - - - Sort notes in folder <span style="%1">%2</span> in the configuration file. - 对文件夹 <span style="%1">%2</span> 的笔记在配置文件中进行排序。 - - - - Name - 名字 - - - - Created Time - 创建时间 - - - - Modified Time - 修改时间 - - - - Fail to sort notes in folder <span style="%1">%2</span>. - 对文件夹 <span style="%1">%2</spacn> 的笔记排序失败。 - - - - Open With - 其他打开方式 - - - - Open current note with %1 - 使用 %1 打开当前笔记 - - - - System's Default Program - 系统默认程序 - - - - Open current note with system's default program - 使用系统默认程序打开当前笔记 - - - - View and edit current note's information - 查看并编辑当前笔记的信息 - - - - Copy selected notes - 复制选定笔记 - - - - Cut selected notes - 剪切选定笔记 - - - - Note Information - 笔记信息 - - - - Fail to rename note <span style="%1">%2</span>. - 重命名笔记 <span style="%1">%2</span> 失败。 - - - - Create a note in <span style="%1">%2</span>. - 在目录 <span style="%1">%2</span> 中新建笔记。 - - - - Note with name ending with "%1" will be treated as Markdown type. - 名字后缀为“%1”的笔记是Markdown笔记。 - - - - Fail to create note <span style="%1">%2</span>. - 新建笔记 <span style="%1">%2</span> 失败。 - - - - - Fail to copy note <span style="%1">%2</span>. - 复制笔记 <span style="%1">%2</span> 失败。 - - - - Create a note in current folder - 在当前文件夹中新建笔记 - - - - &Info %1 - 信息 (&I) %1 - - - - &Copy %1 - 复制 (&C) %1 - - - - C&ut %1 - 剪切 (&U) %1 - - - - &Paste %1 - 粘贴 (&P) %1 - - - - Paste notes in current folder - 在当前文件夹中粘贴笔记 - - - - &Open Note Location - 打开笔记所在位置 (&O) - - - - Open the folder containing this note in operating system - 在操作系统中打开该笔记所在目录 - - - - Create Note - 新建笔记 - - - - - - - - - - Warning - 警告 - - - - VFindReplaceDialog - - - Find/Replace - 查找/替换 - - - - Find: - 查找: - - - - Enter text to search - 输入要查找的文本 - - - - Find &Next - 查找下一个 (&N) - - - - Find &Previous - 查找上一个 (&P) - - - - &Replace with: - 替换 (&R): - - - - Enter text to replace with - 输入替换后的文本 - - - - Replace - 替换 - - - - Replace && Fin&d - 替换并查找 (&D) - - - - Replace A&ll - 全部替换 (&L) - - - - &Advanced >> - 高级 (&A) >> - - - - &Case sensitive - 区分大小写 (&C) - - - - &Whole word only - 完整字词匹配 (&W) - - - - Re&gular expression - 正则表达式 (&G) - - - - &Incremental search - 增量查找 (&I) - - - - VGeneralTab - - - Choose the language of VNote interface - 选择VNote界面语言 - - - - System - 默认 - - - - Language: - 语言: - - - - Startup pages: - 启动页面: - - - - Restore tabs or open specific notes on startup - 在启动时恢复标签页或打开指定笔记 - - - - None - - - - - Continue where you left off - 继续上次退出时的页面 - - - - Open specific pages - 打开指定页面 - - - - Absolute path of the notes to open on startup (one note per line) - 需要在启动时打开的笔记的绝对路径(一行一个笔记) - - - - Browse - 浏览文件 - - - - Select files to add as startup pages - 选择文件添加为启动页面 - - - - Select Files As Startup Pages - 选择文件作为启动页面 - - - - System tray - 系统托盘 - - - - Minimized to the system tray after closing VNote (not supported in macOS) - 关闭VNote后最小化到系统托盘(不支持macOS) - - - - VHtmlTab - - - Information - 注意 - - - - Note <span style="%1">%2</span> has been modified. - 笔记 <span style="%1">%2</span> 已经被更改。 - - - - Do you want to save your changes? - 是否保存更改? - - - - - - Warning - 警告 - - - - Could not modify a read-only note <span style="%1">%2</span>. - 无法修改只读笔记 <span style="%1">%2</span>。 - - - - Please save your changes to other notes manually. - 请手动保存更改到其他笔记。 - - - - - Fail to save note. - 保存笔记失败。 - - - - File <span style="%1">%2</span> being written has been removed. - 将要写入的文件 <span style="%1">%2</span> 已经被移除。 - - - - Fail to write to disk when saving a note. Please try it again. - 保存笔记时,写入文件失败。请稍后再试。 - - - - VInsertImageDialog - - - &From: - 图片源 (&F): - - - - &Browse - 浏览文件 (&B) - - - - &Image title: - 图片标题 (&I): - - - - Select The Image To Be Inserted - 选择要插入的图片 - - - - Images (*.png *.xpm *.jpg *.bmp *.gif) - 图片 (*.png *.xpm *.jpg *.bmp *.gif) - - - - VInsertLinkDialog - - - Absolute or relative path of the link - 链接的绝对或相对路径 - - - - &Text: - 文本 (&T): - - - - &URL: - URL (&U): - - - - VMainWindow - - - View - 查看 - - - - &Single Panel - 单列面板 (&S) - - - - Display only the notes list panel - 仅显示笔记列表面板 - - - - &Two Panels - 双列面板 (&T) - - - - Display both the folders and notes list panel - 显示文件夹树和笔记列表面板 - - - - &Compact Mode - 紧凑模式 (&C) - - - - Integrate the folders and notes list panel in one column - 将文件夹和笔记列表面板整合到一列 - - - - Expand the edit area - 扩展内容编辑区域 - - - - Edit Toolbar - 编辑工具栏 - - - - Heading Sequence - 标题序列 - - - - Enable heading sequence in current note in edit mode - 当前笔记在编辑模式中启用标题序列 - - - Bold (Ctrl+B) - 粗体 (Ctrl+B) - - - - Insert bold text or change selected text to bold - 插入粗体或将所选文本加粗 - - - Italic (Ctrl+I) - 斜体 (Ctrl+I) - - - - Insert italic text or change selected text to italic - 插入斜体或将所选文本改为斜体 - - - Strikethrough (Ctrl+D) - 删除线 (Ctrl+D) - - - - Insert strikethrough text or change selected text to strikethroughed - 插入删除线或在所选文本上添加删除线 - - - Inline Code (Ctrl+O) - 行内代码 (Ctrl+O) - - - - Insert inline-code text or change selected text to inline-coded - 插入行内代码或将所选文本改为行内代码 - - - Code Block (Ctrl+M) - 代码块 (Ctrl+M) - - - - Insert fenced code block text or wrap selected text into a fenced code block - 插入代码块或将所选文本嵌入到一个代码块中 - - - Insert Link (Ctrl+L) - 插入链接 (Ctrl+L) - - - - Insert a link - 插入一个链接 - - - Insert Image - 插入图片 - - - - Insert an image from file or URL - 从文件或URL插入图片 - - - - Toggle the edit toolbar - 打开或关闭编辑工具栏 - - - - Note - 笔记 - - - - New &Note - 新建笔记 (&N) - - - - Note &Info - 笔记信息 (&I) - - - - View and edit current note's information - 查看并编辑当前笔记的信息 - - - - &Delete Note - 删除笔记 (&D) - - - - Delete current note - 删除当前笔记 - - - - - &Edit - 编辑 (&E) - - - - Edit current note - 编辑当前笔记 - - - - Discard changes and exit edit mode - 放弃对当前笔记的更改并退出编辑模式 - - - Discard Changes And Read (Ctrl+E Q) - 放弃更改并阅读 (Ctrl+E Q) - - - Save Changes And Read (Ctrl+T) - 保存更改并阅读 (Ctrl+T) - - - - Save changes and exit edit mode - 保存对当前笔记的更改并退出编辑模式 - - - - Save - 保存 - - - - &Help - 帮助 (&H) - - - - View &Log - 查看日志 (&L) - - - - View VNote's debug log (%1) - 查看VNote的调试日志 (%1) - - - - &Markdown Guide - Markdown指南 (&M) - - - - A quick guide of Markdown syntax - Markdown语法快速指南 - - - - Check For &Updates - 检查更新 (&U) - - - - Check for updates of VNote - 检查VNote的可用更新 - - - - Star VNote on &Github - 支持VNote &Github项目 - - - - Give a star to VNote on Github project - 在Github上给一个星星VNote项目 - - - - &Feedback - 反馈 (&F) - - - - Open an issue on Github - 在Github上反馈意见 - - - - About &Qt - 关于Qt (&Q) - - - - &Markdown - Markdown (&M) - - - - Open Configuration Folder - 打开配置文件夹 - - - - Open configuration folder of VNote - 打开VNote的配置文件夹 - - - - &Converter - 渲染引擎 (&C) - - - - Marked - Marked - - - - Use Marked to convert Markdown to HTML (re-open current tabs to make it work) - 使用Marked对Markdown进行HTML渲染(需要重新打开当前标签页) - - - - Hoedown - Hoedown - - - - Use Hoedown to convert Markdown to HTML (re-open current tabs to make it work) - 使用Hoedown对Markdown进行HTML渲染(需要重新打开当前标签页) - - - - Markdown-it - Markdown-it - - - - Use Markdown-it to convert Markdown to HTML (re-open current tabs to make it work) - 使用Markdown-it对Markdown进行HTML渲染(需要重新打开当前标签页) - - - - Showdown - Showdown - - - - Use Showdown to convert Markdown to HTML (re-open current tabs to make it work) - 使用Showdown对Markdown进行HTML渲染(需要重新打开当前标签页) - - - - Constrain The Width of Images - 限制图片宽度 - - - - AttachmentList - 附件列表 - - - - LocateCurrentFile - 定位当前笔记 - - - - ExpandMode - 扩展模式 - - - - OnePanelView - 单列面板模式 - - - - DiscardAndRead - 放弃更改并阅读 - - - - ToolsDock - 工具窗口 - - - - CloseNote - 关闭笔记 - - - - ShortcutsHelp - 快捷键帮助 - - - - FlushLogFile - 写入日志文件 - - - Inline Code (Ctrl+K) - 行内代码 (Ctrl+K) - - - - Constrain the width of images to the window in read mode (re-open current tabs to make it work) - 阅读模式中根据窗口大小限制图片的宽度(需要重新打开当前标签页) - - - - Enable Image Caption - 启用图片标题 - - - - Center the images and display the alt text as caption (re-open current tabs to make it work) - 居中显示图片并将图片的替换文本显示为标题(需要重新打开当前标签页) - - - - &Mermaid Diagram - Mermaid图表 (&M) - - - - Enable Mermaid for graph and diagram - 启用Mermaid渲染图像图表 - - - - &Flowchart.js - &Flowchart.js - - - - Enable Flowchart.js for flowchart diagram - 启用Flowchart.js渲染流程图 - - - - Preview Images In Edit Mode - 编辑模式预览图片 - - - - Constrain The Width Of Previewed Images - 限制预览图片宽度 - - - - Constrain the width of previewed images to the edit window in edit mode - 编辑模式中根据编辑窗口大小限制预览图片的宽度 - - - - &View - 查看 (&V) - - - - &File - 文件 (&F) - - - - &Open - 打开 (&O) - - - - Open external file to edit - 打开外部文件以编辑 - - - - Select External Files To Open - 选择要打开的外部文件 - - - Open the folder to add your custom CSS style files for Markdown rendering - 打开样式文件夹以添加自定义Markdown渲染CSS样式文件 - - - Set as the code block CSS style for Markdown rendering - 使用该CSS样式对Markdown的代码块进行渲染 - - - - Code Block Style - 代码块样式 - - - Open the folder to add your custom CSS style files for Markdown code block rendering - 打开样式文件夹以添加自定义Markdown代码块渲染CSS样式文件 - - - - CodeBlock - 代码块 - - - - Display line number in code block in edit mode (for Markdown only) - 编辑模式下只在代码块显示行号(仅支持Markdown) - - - - Set as the editor style (re-open current tabs to make it work) - 设置为编辑器的样式(需要重新打开当前标签页) - - - - Show VNote - 显示VNote - - - - Quit - 退出VNote - - - - VNote - VNote - - - - View and change settings for VNote - 查看并更改VNote的配置 - - - - Note Toolbar - 笔记工具栏 - - - - Attachments (drag files here to add attachments) - 附件(拖动文件到此以添加附件) - - - - &Wiki - 维基 (&W) - - - - View VNote's wiki on Github - 查看VNote在Github上的维基 - - - - Display Line Number In Code Blocks - 代码块显示行号 - - - - Enable line number in code blocks in read mode - 阅读模式下启用代码块行号 - - - - Enable image preview in edit mode (re-open current tabs to make it work) - 编辑模式预览图片(需要重新打开当前标签页) - - - Edit Configuration File - 编辑配置文件 - - - View and edit configuration file of VNote (vnote.ini) - 查看并编辑VNote的配置文件(vnote.ini) - - - - - Custom Shortcuts - 自定义快捷键 - - - - Custom some standard shortcuts - 自定义部分标准快捷键 - - - - VNote supports customing some standard shorcuts by editing user's configuration file (vnote.ini). Please reference the shortcuts help documentation for more information. - VNote支持通过修改用户配置文件(vnote.ini)来自定义部分标准快捷键。更多信息请参考快捷键帮助文档。 - - - - Click "OK" to custom shortcuts. - 点击“确认”以自定义快捷键。 - - - Insert &Image - 插入图片 (&I) - - - - - Find/Replace - 查找/替换 - - - - Open Find/Replace dialog to search in current note - 打开查找/替换对话框以在当前笔记中查找 - - - - Find Next - 查找下一个 - - - - Find next occurence - 查找下一处出现 - - - - Find Previous - 查找上一个 - - - - Find previous occurence - 查找上一处出现 - - - - Replace - 替换 - - - - Replace current occurence - 替换当前出现 - - - - Replace && Find - 替换并查找 - - - - Replace current occurence and find the next one - 替换当前出现并查找下一个 - - - - Replace All - 全部替换 - - - - Replace all occurences in current note - 替换当前笔记中的所有出现 - - - - Highlight Searched Pattern - 高亮查找模式 - - - - Highlight all occurences of searched pattern - 高亮查找模式的所有出现 - - - - &Expand Tab - 扩展Tab (&E) - - - - Expand entered Tab to spaces - 将输入的Tab扩展为空格 - - - - Expand Tab to 2 spaces - 扩展Tab为2个空格 - - - - Expand Tab to 4 spaces - 扩展Tab为4个空格 - - - - Expand Tab to 8 spaces - 扩展Tab为8个空格 - - - - Auto Indent - 自动缩进 - - - - Indent automatically when inserting a new line - 插入新行时自动缩进 - - - - Auto List - 自动列表 - - - - Continue the list automatically when inserting a new line - 插入新行时自动继续列表 - - - - Vim Mode - Vim模式 - - - - Highlight Selected Words - 高亮选定字词 - - - - Highlight all occurences of selected words - 高亮选定字词的所有出现 - - - - Highlight Trailing Sapces - 高亮行尾空白字符 - - - - Highlight all the spaces at the end of a line - 高亮所有行尾空白字符 - - - - Snippets - 片段 - - - - Select Files To Create Notes - 选择文件以创建笔记 - - - - Warning - 警告 - - - - Fail to create notes for all the files. - 无法从所有文件中创建笔记。 - - - - %1 %2 created from external files - 从外部文件夹中创建了%1个%2 - - - - notes - 笔记 - - - - note - 笔记 - - - - <span style="font-weight: bold;">v%1</span> - - - - - Please visit <a href="https://github.com/tamlok/vnote.git">Github</a> for more information. - 请访问<a href="https://github.com/tamlok/vnote.git">Github</a>获取更多信息。 - - - - Markdown-it Options - Markdown-it选项 - - - - HTML - HTML - - - - Enable HTML tags in source - 启用文件中的HTML标签 - - - - Line Break - 换行 - - - - Convert '\n' in paragraphs into line break - 转换'\n'为换行 - - - - Linkify - 自动链接 - - - - Convert URL-like text into links - 转换URL模式的文本为链接 - - - - Use system's background color configuration for Markdown rendering - 使用系统的背景色设置对Markdown进行渲染 - - - - Set as the background color for Markdown rendering - 使用该背景色对Markdown进行渲染 - - - - Headings - 标题 - - - - Heading %1 - 标题%1 - - - - Heading %1 %2 - 标题%1 %2 - - - - Clear - 清空标题 - - - - Clear %1 - 清空标题 %1 - - - - Theme - 主题 - - - - Set as the theme of VNote (restart VNote to make it work) - 设置为VNote的主题(重启VNote生效) - - - &Add Style - 添加样式 (&A) - - - - Line Number - 行号 - - - - None - - - - - Do not display line number in edit mode - 编辑模式下不显示行号 - - - - Absolute - 绝对行号 - - - - Display absolute line number in edit mode - 编辑模式下显示绝对行号 - - - - Relative - 相对行号 - - - - Display line number relative to current cursor line in edit mode - 编辑模式下显示相对于当前光标所在行的行号 - - - - Editor &Style - 编辑器样式 (&S) - - - Open the folder to add your custom MDHL style files - 打开样式文件夹以添加自定义MDHL样式文件 - - - - Close VNote - 关闭VNote - - - - Do you want to minimize VNote to system tray instead of quitting it when closing VNote? - 关闭VNote时是否仅将VNote最小化到系统托盘? - - - - You could change the option in Settings later. - 稍后可以进入设置改变该选项。 - - - - Print Note - 打印笔记 - - - Set as the editor style - 使用该样式设置编辑器 - - - - 2 Spaces - 2个空格 - - - - - Discard Changes And Read - 放弃更改并阅读 - - - - Single Panel - 单列面板 - - - - Two Panels - 双列面板 - - - - Expand - 扩展 - - - - Bold %1 - 粗体 %1 - - - - Italic %1 - 斜体 %1 - - - - Strikethrough %1 - 删除线 %1 - - - - Inline Code %1 - 行内代码 %1 - - - - Code Block %1 - 代码块 %1 - - - - Insert Link %1 - 插入链接 %1 - - - - Insert Image %1 - 插入图片 %1 - - - - Flash Page - 灵犀页 - - - - Open the Flash Page to edit - 打开灵犀页进行编辑 - - - - Save Changes And Read - 保存更改并阅读 - - - - Save changes to current note - 保存对当前笔记的更改 - - - - &Shortcuts Help - 快捷键帮助 (&S) - - - - View information about shortcut keys - 查看快捷键帮助信息 - - - - &About VNote - 关于VNote (&A) - - - - View information about VNote - 查看VNote的信息 - - - - View information about Qt - 查看Qt的信息 - - - - Math&Jax - Math&Jax - - - - Enable MathJax for math support in Markdown - 启用MathJax渲染数学公式 - - - - Highlight Code Blocks In Edit Mode - 编辑模式高亮代码块 - - - - Enable syntax highlight within code blocks in edit mode - 编辑模式中启用代码块语法高亮 - - - - &New Notes From Files - 从文件新建笔记 (&N) - - - - Create notes from external files in current folder by copy - 通过拷贝外部文件在当前文件夹中新建笔记 - - - - Export As &PDF - 导出为&PDF - - - - Export current note as PDF file - 将当前笔记导出为PDF文件 - - - - &Print - 打印 (&P) - - - - Print current note - 打印当前笔记 - - - - &Settings - 设置 (&S) - - - Insert an image from file into current note - 从文件中插入图片到当前笔记 - - - - 4 Spaces - 4个空格 - - - - 8 Spaces - 8个空格 - - - - Enable Vim mode for editing (re-open current tabs to make it work) - 编辑时启用Vim模式(需要重新打开当前标签页) - - - - Smart Input Method In Vim Mode - Vim模式智能输入法 - - - - Disable input method when leaving Insert mode in Vim mode - Vim模式中,退出插入模式时禁用输入法 - - - - Highlight Cursor Line - 高亮光标所在行 - - - - Highlight current cursor line - 高亮当前光标所在行 - - - - Tab Stop Width - Tab Stop宽度 - - - - Tools - 工具 - - - - Outline - 大纲 - - - - Toggle the tools dock widget - 打开或关闭工具窗口 - - - - VNote is a Vim-inspired note-taking application for Markdown. - VNote是一个受Vim启发而开发的专注于Markdown的笔记软件。 - - - - About VNote - 关于VNote - - - - &Rendering Background - 渲染背景 (&R) - - - - - System - 默认 - - - - Rendering &Style - 渲染样式 (&S) - - - Set as the CSS style for Markdown rendering - 使用该CSS样式对Markdown进行渲染 - - - - Notebooks - 笔记本 - - - - Folders - 文件夹 - - - Single Panel (Ctrl+E P) - 单列面板 (Ctrl+E P) - - - Two Panels (Ctrl+E P) - 双列面板 (Ctrl+E P) - - - Expand (Ctrl+E E) - 扩展 (Ctrl+E E) - - - - New &Root Folder - 新建根文件夹 (&R) - - - - Create a root folder in current notebook - 在当前笔记本中新建根文件夹 - - - - Create a note in current folder - 在当前文件夹中新建笔记 - - - - &Quit - 退出 (&Q) - - - - Quit VNote - 退出VNote - - - - Set as the CSS style for Markdown rendering (re-open current tabs to make it work) - 设置为Markdown渲染的CSS样式(需要重新打开当前标签页) - - - - Set as the code block CSS style for Markdown rendering (re-open current tabs to make it work) - 设置为Markdown渲染的代码块CSS样式(需要重新打开当前标签页) - - - - &Background Color - 背景颜色 (&B) - - - - Use system's background color configuration for editor - 为编辑器使用系统的背景色设置 - - - - Set as the background color for editor - 使用该背景色设置编辑器 - - - - VMarkdownTab - - - Default mode to open a note - 笔记默认打开模式 - - - - Read Mode - 阅读模式 - - - - Edit Mode - 编辑模式 - - - - Note open mode: - 笔记打开模式: - - - Heading sequence - 标题序列 - - - - Enable auto sequence for all headings (in the form like 1.2.3.4.) - 自动为所有标题添加序列(类似于1.2.3.4.) - - - - Disabled - 关闭 - - - - Enabled - 启用 - - - - Enabled for notes only - 仅对内部笔记启用 - - - - Base level to start heading sequence - 标题序列起始级别 - - - - 1 - 1 - - - - 2 - 2 - - - - 3 - 3 - - - - 4 - 4 - - - - 5 - 5 - - - - 6 - 6 - - - - Custom Web zoom factor - 自定义页面缩放倍数 - - - - Set the zoom factor of the Web page when reading - 设置阅读模式下页面的缩放倍数 - - - - Specify the screen column in fenced code block which will be highlighted - 指定编辑模式下代码块中的高亮列 - - - - Color column: - 高亮列: - - - - Heading sequence: - 标题序列: - - - - VMdEdit - - - Insert From Clipboard - 粘贴选项 - - - - Insert As Image - 作为图像插入 - - - - Insert As Text - 作为文本插入 - - - - Following images seems not to be used in this note anymore. Please confirm the deletion of these images. - 下列图片似乎已经不再在该笔记中被使用。请确认是否删除这些图片。 - - - - Deleted files could be found in the recycle bin of this note.<br>Click "Cancel" to leave them untouched. - 被删除的文件可以在该笔记的回收站中找回。<br>点击“取消”以终止操作。 - - - - Confirm Cleaning Up Unused Images - 确认清理未被使用的图片 - - - - VMdEditOperations - - - Insert Image From Clipboard - 从剪切板中插入图片 - - - - - Fail to create image folder <span style="%1">%2</span>. - 新建图片目录 <span style="%1">%2</span> 失败。 - - - - Fail to save image <span style="%1">%2</span>. - 保存图片 <span style="%1">%2</span> 失败。 - - - - - Warning - 警告 - - - - - Fail to insert image <span style="%1">%2</span>. - 插入图片 <span style="%1">%2</span> 失败。 - - - - Fail to copy image <span style="%1">%2</span>. - 复制图片 <span style="%1">%2</span> 失败。 - - - - Insert Image - 插入图片 - - - Insert Image From File - 从文件中插入图片 - - - - VMdEditor - - - &Save Changes And Read - 保存更改并阅读 (&S) - - - - Save changes and exit edit mode - 保存对当前笔记的更改并退出编辑模式 - - - - &Discard Changes And Read - 放弃更改并阅读 (&D) - - - - Discard changes and exit edit mode - 放弃对当前笔记的更改并退出编辑模式 - - - - Following images seems not to be used in this note anymore. Please confirm the deletion of these images. - 下列图片似乎已经不再在该笔记中被使用。请确认是否删除这些图片。 - - - - Deleted files could be found in the recycle bin of this note.<br>Click "Cancel" to leave them untouched. - 被删除的文件可以在该笔记的回收站中找回。<br>点击“取消”以终止操作。 - - - - Confirm Cleaning Up Unused Images - 确认清理未被使用的图片 - - - - Insert From Clipboard - 粘贴选项 - - - - Insert As Image - 作为图像插入 - - - - Insert As Text - 作为文本插入 - - - - VMdTab - - - Information - 注意 - - - - Note <span style="%1">%2</span> has been modified. - 笔记 <span style="%1">%2</span> 已经被更改。 - - - - Do you want to save your changes? - 是否保存更改? - - - - - - Warning - 警告 - - - - Could not modify a read-only note <span style="%1">%2</span>. - 无法修改只读笔记 <span style="%1">%2</span>。 - - - - Please save your changes to other notes manually. - 请手动保存更改到其他笔记。 - - - - - Fail to save note. - 保存笔记失败。 - - - - File <span style="%1">%2</span> being written has been removed. - 将要写入的文件 <span style="%1">%2</span> 已经被移除。 - - - - Fail to write to disk when saving a note. Please try it again. - 保存笔记时,写入文件失败。请稍后再试。 - - - - Snippet applied - 片段已应用 - - - - Snippet %1 is not applicable - 片段 %1 不适用 - - - - Snippets are not applicable - 无法应用片段 - - - - No available snippets defined with shortcuts - 当前没有定义带有快捷键的片段可用 - - - - Backup File Found - 发现备份文件 - - - - Found backup file <span style="%1">%2</span> when opening note <span style="%1">%3</span>. - 打开笔记 <span style="%1">%3</span> 时发现备份文件 <span style="%1">%2</span>。 - - - - VNote may crash while editing this note before.<br/>Please choose to recover from the backup file or delete it.<br/><br/>Note file last modified: <span style="%1">%2</span><br/>Backup file last modified: <span style="%1">%3</span><br/>Content comparison: <span style="%1">%4</span> - VNote此前编辑该笔记时可能意外退出。<br/>请选择从该备份文件恢复或者删除该备份文件。<br/><br/>笔记文件上次修改时间: <span style="%1">%2</span><br/>备份文件上次修改时间: <span style="%1">%3</span><br/>内容比较: <span style="%1">%4</span> - - - - Identical - 一致 - - - - Different - 有区别 - - - - Recover From Backup File - 从备份文件恢复 - - - - Discard Backup File - 放弃备份文件 - - - - Cancel - 取消 - - - - VMetaWordManager - - - the day as number without a leading zero (`1` to `31`) - 没有前导零的日期数字(`1` 到 `31`) - - - - the day as number with a leading zero (`01` to `31`) - 带有前导零的日期数字(`01` 到 `31`) - - - - the abbreviated localized day name (e.g. `Mon` to `Sun`) - 缩写日期名字(如 `一` 到 `日`) - - - - the long localized day name (e.g. `Monday` to `Sunday`) - 完整日期名字(如 `星期一` 到 `星期日`) - - - - the month as number without a leading zero (`1` to `12`) - 没有前导零的月份数字(`1` 到 `12`) - - - - the month as number with a leading zero (`01` to `12`) - 带有前导零的月份数字(`01` 到 `12`) - - - - the abbreviated localized month name (e.g. `Jan` to `Dec`) - 缩写月份名字(如 `一` 到 `十二`) - - - - the year as two digit number (`00` to `99`) - 两位数的年份数字(`00` 到 `99`) - - - - the year as four digit number - 四位数的年份数字 - - - - the long localized month name (e.g. `January` to `December`) - 完整月份名字(如 `一月` 到 `十二月`) - - - - the hour without a leading zero (`0` to `23` or `1` to `12` if AM/PM display) - 没有前导零的小时(`0` 到 `23` 或者 `1` 到 `12`) - - - - the hour with a leading zero (`00` to `23` or `01` to `12` if AM/PM display) - 带有前导零的小时(`00` 到 `23` 或者 `01` 到 `12`) - - - - the hour without a leading zero (`0` to `23` even with AM/PM display) - 没有前导零的小时(`0` 到 `23`) - - - - the hour with a leading zero (`00` to `23` even with AM/PM display) - 带有前导零的小时(`0` 到 `23`) - - - - the minute without a leading zero (`0` to `59`) - 没有前导零的分钟(`0` 到 `59`) - - - - the minute with a leading zero (`00` to `59`) - 带有前导零的分钟(`0` 到 `59`) - - - - the second without a leading zero (`0` to `59`) - 没有前导零的秒(`0` 到 `59`) - - - - the second with a leading zero (`00` to `59`) - 带有前导零的秒(`00` 到 `59`) - - - - the milliseconds without leading zeroes (`0` to `999`) - 没有前导零的毫秒(`0` 到 `999`) - - - - the milliseconds with leading zeroes (`000` to `999`) - 带有前导零的毫秒(`000` 到 `999`) - - - - - use AM/PM display (`AM` or `PM`) - 显示AM或PM - - - - - use am/pm display (`am` or `pm`) - 显示am或pm - - - - the timezone (e.g. `CEST`) - 时区(如 `CEST`) - - - - a random number - 随机数 - - - - dynamic version of `random` - 随机数(动态) - - - - name of current note - 当前笔记名字 - - - - complete base name of current note - 当前笔记的完整基本名字 - - - - information about all defined magic words - 列出所有幻词的信息 - - - - VNewDirDialog - - - Folder &name: - 文件夹名 (&N): - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写) <span style="%2">%3</span>。请选择另一个名字。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>:名字 <span style="%2">%3</span> 包含非法字符(解析幻词之后)。 - - - <span style="%1">WARNING</span>: Name (case-insensitive) already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写)。请选择另一个名字。 - - - - VNewFileDialog - - - Note &name: - 笔记名 (&N): - - - - Insert note name as title (for Markdown only) - 将笔记名字作为标题插入(仅支持Markdown) - - - - Choose a template (magic word supported) - 选择一个模板 (支持幻词) - - - - Manage Templates - 管理模板 - - - - Insert note name into the new note as a title - 将笔记名字作为标题插入到新建的笔记中 - - - - Template: - 模板: - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写) <span style="%2">%3</span>。请选择另一个名字。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>:名字 <span style="%2">%3</span> 包含非法字符(解析幻词之后)。 - - - - None - - - - <span style="%1">WARNING</span>: Name (case-insensitive) already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写)。请选择另一个名字。 - - - - VNewNotebookDialog - - - Notebook &name: - 笔记本名 (&N): - - - - Notebook &root folder: - 笔记本根文件夹 (&R): - - - - &Image folder: - 图片文件夹 (&I): - - - - - Use global configuration (%1) - 使用全局配置 (%1) - - - - Set the name of the folder to hold images of all the notes in this notebook (empty to use global configuration) - 设置一个文件夹以保存该笔记本下所有笔记的图片(为空则使用全局配置) - - - - &Attachment folder: - 附件文件夹 (&A): - - - - Set the name of the folder to hold attachments of all the notes in this notebook (empty to use global configuration, read-only once created) - 设置一个文件夹以保存该笔记本下所有笔记的附件(为空则使用全局配置,创建后不可修改) - - - - <span style="%1">WARNING</span>: The folder chosen is NOT empty! It is highly recommended to use an EMPTY and EXCLUSIVE folder for a new notebook. - <span style="%1">警告</span>:所选的文件夹不是空的!强烈建议为一个新的笔记本指定一个空的、独占的文件夹。 - - - - <span style="%1">INFO</span>: The folder chosen seems to be a root folder of a notebook created by VNote before. VNote will try to import it by reading the configuration file. - <span style="%1">注意</span>:所选的文件夹可能是此前VNote创建的一个笔记本的根文件夹。VNote会尝试读取配置文件并导入该笔记本。 - - - - <span style="%1">WARNING</span>: The path seems to be illegal. Please choose another one. - <span style="%1">警告</span>:根目录路径可能是非法的。请选择另一个路径。 - - - - <span style="%1">WARNING</span>: The folder chosen has already been a root folder of existing notebook <span style="%2">%3</span> in VNote. - <span style="%1">警告</span>:所选的文件夹已经是当前VNote中一个笔记本 <span style="%2">%3</span> 的根文件夹。 - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写) <span style="%2">%3</span>。请选择另一个名字。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>:名字 <span style="%2">%3</span> 包含非法字符(解析幻词之后)。 - - - <span style="%1">WARNING</span>: Name (case-insensitive) already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写)。请选择另一个名字。 - - - - Select Root Folder Of The Notebook - 选择笔记本根文件夹 - - - - &Browse - 浏览文件 (&B) - - - - VNoteFile - - - Fail to delete images of this note. - 删除笔记的图片失败。 - - - - Fail to delete attachments of this note. - 删除笔记的附件失败。 - - - - Fail to delete the note file. - 删除笔记文件失败。 - - - - Fail to remove the note from the folder configuration. - 从文件夹配置中移除笔记失败。 - - - - Fail to open target folder. - 打开目标文件夹失败。 - - - - cut - 剪切 - - - - copy - 复制 - - - - Fail to %1 the note file. - %1笔记文件失败。 - - - - Fail to add the note to target folder's configuration. - 将该笔记添加到目标文件夹的配置失败。 - - - - Source image %1 does not exist. - 源图片 %1 不存在。 - - - - Skip image with the same source and target path %1. - 跳过源和目标路径 %1 相同的图片。 - - - - Fail to %1 image %2 to %3. Please manually %1 it and modify the note. - %1图片 %2 到 %3 失败。请手动%1并修改笔记。 - - - - Fail to %1 attachments folder %2 to %3. Please manually maintain it. - %1附件文件夹 %2 到 %3 失败。请手动维护。 - - - - Fail to update configuration of note %1. - 更新笔记 %1 的配置失败。 - - - - VNoteManagementTab - - - Notes - 笔记 - - - - External Files - 外部文件 - - - - - Custom image folder - 自定义图片文件夹 - - - - Set the global name of the image folder to hold images of notes (restart VNote to make it work) - 全局设置图片文件夹的名字以保存笔记的图片(重启VNote生效) - - - - Custom attachment folder - 自定义附件文件夹 - - - - Set the global name of the attachment folder to hold attachments of notes (restart VNote to make it work) - 全局设置附件文件夹的名字以保存笔记的附件(重启VNote生效) - - - - Name of the attachment folder - 附件文件夹的名字 - - - - Set the path of the global image folder to hold images of external files (restart VNote to make it work). -You could use both absolute or relative path here. If absolute path is used, VNote will not manage -those images, so you need to clean up unused images manually. - 全局设置图片文件夹的路径以保存外部文件的图片(重启VNote生效)。 -这里可以使用绝对路径或者相对路径。如果使用绝对路径,VNote不会管理 -这些图片,需要由用户手动清理不再使用的图片。 - - - - - Name of the image folder - 图片文件夹的名字 - - - - VNotebookInfoDialog - - - Set the name of the folder to hold images of all the notes in this notebook (empty to use global configuration) - 设置一个文件夹以保存该笔记本下所有笔记的图片(为空则使用全局配置) - - - - The folder to hold attachments of all the notes in this notebook - 保存该笔记本下所有笔记的附件的文件夹 - - - - The folder to hold deleted files from within VNote of all the notes in this notebook - 保存该笔记本的所有笔记在VNote中被删除的文件的文件夹 - - - - Notebook &name: - 笔记本名 (&N): - - - - Notebook &root folder: - 笔记本根文件夹 (&R): - - - - &Image folder: - 图片文件夹 (&I): - - - - Attachment folder: - 附件文件夹: - - - - Recycle bin folder: - 回收站文件夹: - - - - Created time: - 创建时间: - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写) <span style="%2">%3</span>。请选择另一个名字。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>:名字 <span style="%2">%3</span> 包含非法字符(解析幻词之后)。 - - - - - Use global configuration (%1) - 使用全局配置 (%1) - - - <span style="%1">WARNING</span>: Name (case-insensitive) already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写)。请选择另一个名字。 - - - - VNotebookSelector - - - &Delete - 删除 (&D) - - - - Delete current notebook - 删除当前笔记本 - - - - &Info - 信息 (&I) - - - - View and edit current notebook's information - 查看并编辑当前笔记本的信息 - - - - &Open Notebook Location - 打开笔记本所在位置 (&O) - - - - Open the root folder of this notebook in operating system - 在操作系统中打开该笔记本的根文件夹 - - - - &Recycle Bin - 回收站 (&R) - - - - Open the recycle bin of this notebook - 打开该笔记本的回收站 - - - - &Empty Recycle Bin - 清空回收站 (&E) - - - - Empty the recycle bin of this notebook - 清空该笔记本的回收站 - - - - Are you sure to empty recycle bin of notebook <span style="%1">%2</span>? - 确认清空笔记本 <span style="%1">%2</span> 的回收站? - - - - <span style="%1">WARNING</span>: VNote will delete all the files in directory <span style="%2">%3</span>.<br>It may be UNRECOVERABLE! - <span style="%1">警告</span>:VNote会删除目录 <span style="%2">%3</span> 中的所有文件。<br>该操作可能是不可恢复的! - - - - Successfully emptied recycle bin of notebook <span style="%1">%2</span>! - 成功清空笔记本 <span style="%1">%2</span> 的回收站! - - - - Fail to empty recycle bin of notebook <span style="%1">%2</span>! - 清空笔记本 <span style="%1">%2</span> 的回收站失败! - - - - Information - 注意 - - - - Create or import a notebook - 新建或导入一个笔记本 - - - - View and edit notebooks - 查看并编辑笔记本 - - - - * The root folder should be used EXCLUSIVELY by VNote and it is recommended to be EMPTY. - * 根目录应该给VNote单独使用,并且推荐使用空文件夹。 - - - - * A previously created notebook could be imported into VNote by choosing its root folder. - * 选择一个此前创建的笔记本的根目录可以将该笔记本导入VNote。 - - - - - Warning - 警告 - - - - Fail to create notebook <span style="%1">%2</span> in <span style="%1">%3</span>. - 在 <span style="%1">%3</span> 中新建笔记本 <span style="%1">%2</span> 失败。 - - - - Delete Notebook - 删除笔记本 - - - - Fail to delete the root folder of notebook <span style="%1">%2</span> from disk. You may open the folder and check it manually. - 无法从磁盘中删除笔记本 <span style="%1">%2</span> 的根目录。 请打开该目录并手动检查。 - - - - - Add Notebook - 添加笔记本 - - - - Please type the name of the notebook and choose a folder as the Root Folder of the notebook. - 请输入笔记本的名字并选择一个文件夹作为笔记本的根目录。 - - - - Delete Notebook Folder From Disk - 从磁盘中删除笔记本根目录 - - - - Notebook Information - 笔记本信息 - - - - VOrphanFileInfoDialog - - - File: - 文件: - - - Image folder: - 图片文件夹: - - - - Use global configuration (%1) - 使用全局配置 (%1) - - - - Set the path of the image folder to store images of this file. -If absolute path is used, VNote will not manage those images.(empty to use global configuration) - 设置该文件的图片文件夹的路径以保存相关图片。 -如果使用绝对路径,VNote不会管理这些图片。(为空则使用全局配置) - - - - &Image folder: - 图片文件夹 (&I): - - - - External File Information - 外部文件信息 - - - - VReadEditTab - - - Read Mode (For Markdown Only) - 阅读模式(仅Markdown笔记有效) - - - - Edit Mode - 编辑模式 - - - - VSelectDialog - - - Cancel - 取消 - - - - VSettingsDialog - - - General - 常规 - - - - Read/Edit - 阅读与编辑 - - - - Note Management - 笔记管理 - - - - Settings - 设置 - - - - Markdown - Markdown - - - - - Warning - 警告 - - - - Fail to load configuration. - 读取配置失败。 - - - - Fail to save configuration. Please try it again. - 保存配置失败。请稍后再试。 - - - - VSnippetList - - - - - - - Warning - 警告 - - - - Fail to read snippets from <span style="%1">%2</span>. - 从 <span style="%1">%2</span> 读取片段失败。 - - - - New Snippet - 新建片段 - - - - Open Folder - 打开所在文件夹 - - - - &Apply - 应用 (&A) - - - - Insert this snippet in editor - 在编辑器中插入该片段 - - - - &Info %1 - 信息 (&I) %1 - - - - View and edit snippet's information - 查看并编辑片段的信息 - - - - &Delete - 删除 (&D) - - - - Delete selected snippets - 删除选定片段 - - - - &Sort - 排序 (&S) - - - - Sort snippets manually - 对片段进行手动排序 - - - - - Magic words are supported in the content of the snippet. - 片段内容支持幻词。 - - - - Create Snippet - 新建片段 - - - - Fail to create snippet <span style="%1">%2</span>. - 新建片段 <span style="%1">%2</span> 失败。 - - - - Are you sure to delete these snippets? - 确认删除这些片段? - - - - Click "Cancel" to leave them untouched. - 点击“取消”以终止操作。 - - - - Confirm Deleting Snippets - 确认删除片段 - - - - Fail to delete snippets. - 删除片段失败。 - - - - Sort Snippets - 排序片段 - - - - Sort snippets in the configuration file. - 对片段在配置文件中进行排序。 - - - - Name - 名字 - - - - Fail to sort snippets. - 排序片段失败。 - - - - Snippet Information - 片段信息 - - - - - - - Fail to write snippets configuration file. - 写入片段的配置失败。 - - - - Fail to update information of snippet <span style="%1">%2</span>. - 更新片段 <span style="%1">%2</span> 的信息失败。 - - - - %1 %2 - %1 %2 - - - - Snippets - 片段 - - - - Snippet - 片段 - - - - Fail to add write the snippet file %1. - 写入片段文件 %1 失败。 - - - - Fail to remove snippet file %1. - 删除片段文件 %1 失败。 - - - - VSortDialog - - - &Top - 移到顶部 (&T) - - - - Move selected items to top - 将所选项移动到顶部 - - - - &Up - 上移 (&U) - - - - Move selected items up - 将所选项往上移动一项 - - - - &Down - 下移 (&D) - - - - Move selected items down - 将所选项往下移动一项 - - - - &Bottom - 移到底部 (&B) - - - - Move selected items to bottom - 将所选项移动到底部 - - - - VTabIndicator - - - The type of the file - 文件类型 - - - - ReadOnly - 只读 - - - - This file is read-only - 文件为只读 - - - - Standalone - 独立文件 - - - - This file is not managed by any notebook or folder - 文件未被任何笔记本或文件夹管理 - - - - System - 系统文件 - - - - This file is a system file - 文件为系统文件 - - - - <span><span style="font-weight:bold;">Line</span>: %1 - %2(%3%) <span style="font-weight:bold;">Col</span>: %4</span> - <span><span style="font-weight:bold;">行</span>: %1 - %2(%3%) <span style="font-weight:bold;">列</span>: %4</span> - - - - VUpdater - - - Current Version: v%1 - 当前版本:v%1 - - - - - Checking for updates... - 正在检查更新... - - - - VNote Update - VNote更新 - - - - :( Fail to check for updates. -Please try it later. - :( 检查更新失败。 -请稍后再试。 - - - - Current Version: v%1 -Latest Version: v%2 - 当前版本:v%1 -最新版本:v%2 - - - - <span style="font-weight: bold;">Updates Available!</span><br/>Please visit <a href="%1">Github Releases</a> to download the latest version. - <span style="font-weight: bold;">发现更新!</span><br/>请访问<a href="%1">Github Releases</a>下载最新版本。 - - - - VNote is already the latest version. - VNote当前已经是最新版本。 - - - - VVim - - - - - - %1 %2 changed - 更改了 %1 %2 - - - - - - - - - - - - - - - - - lines - - - - - - - - - - - - - - - - - - line - - - - - Mark not set - 标记未设置 - - - - - - %1 fewer %2 - 少了 %1 %2 - - - - - - %1 %2 yanked - 复制了 %1 %2 - - - - %1 more %2 - 多了 %1 %2 - - - %1 %2 >ed 1 time - %1 %2增加了1次缩进 - - - %1 %2 <ed 1 time - %1 %2减小了1次缩进 - - - - - - %1 %2 %3ed 1 time - %1 %2 %3 了1次 - - - - Undo %1 %2 - 撤销 %1 次%2 - - - - - changes - 更改 - - - - - change - 更改 - - - - Redo %1 %2 - 重做 %1 次%2 - - - - Mark has invalid line number - 标记的行号无效 - - - - - Note has been saved - 已保存笔记 - - - - - Quit - 退出编辑 - - - - - Quit with note having been saved - 保存更改并退出编辑 - - - - Not an editor command: %1 - 不是一个编辑器命令:%1 - - - - VVimIndicator - - - Registers - 寄存器 - - - - Register - 寄存器 - - - - Value - - - - - Marks - 标记 - - - - Mark - 标记 - - - - Line - - - - - Column - - - - - Text - 文本 - - - - Normal - 正常 - - - - Insert - 插入 - - - - Visual - 可视 - - - - VisualLine - 可视行 - - - - Replace - 替换 - - - - Unknown - 未知 - - - - VWebView - - - &Edit - 编辑 (&E) - - - - Edit current note - 编辑当前笔记 - - - diff --git a/src/utils/flowchart.js/README.md b/src/utils/flowchart.js/README.md deleted file mode 100644 index 634eb04e..00000000 --- a/src/utils/flowchart.js/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# [flowchart.js](https://github.com/adrai/flowchart.js) -v1.6.6 -Adriano Raiano - -# [Raphael](https://github.com/DmitryBaranovskiy/raphael) -v2.2.7 diff --git a/src/utils/flowchart.js/flowchart.min.js b/src/utils/flowchart.js/flowchart.min.js deleted file mode 100644 index 9d1cb4fc..00000000 --- a/src/utils/flowchart.js/flowchart.min.js +++ /dev/null @@ -1,7 +0,0 @@ -// flowchart.js, v1.6.6 -// Copyright (c)2017 Adriano Raiano (adrai). -// Distributed under MIT license -// http://adrai.github.io/flowchart.js - -!function(t,i){if("object"==typeof exports&&"object"==typeof module)module.exports=i(require("Raphael"));else if("function"==typeof define&&define.amd)define(["Raphael"],i);else{var e=i("object"==typeof exports?require("Raphael"):t.Raphael);for(var r in e)("object"==typeof exports?exports:t)[r]=e[r]}}(this,function(t){return function(t){function i(r){if(e[r])return e[r].exports;var s=e[r]={exports:{},id:r,loaded:!1};return t[r].call(s.exports,s,s.exports,i),s.loaded=!0,s.exports}var e={};return i.m=t,i.c=e,i.p="",i(0)}([function(t,i,e){e(8);var r=e(4);e(14);var s={parse:r};"undefined"!=typeof window&&(window.flowchart=s),t.exports=s},function(t,i){function e(t,i){if(!t||"function"==typeof t)return i;var r={};for(var s in i)r[s]=i[s];for(s in t)t[s]&&("object"==typeof r[s]?r[s]=e(r[s],t[s]):r[s]=t[s]);return r}function r(t,i){if("function"==typeof Object.create)t.super_=i,t.prototype=Object.create(i.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}});else{t.super_=i;var e=function(){};e.prototype=i.prototype,t.prototype=new e,t.prototype.constructor=t}}t.exports={defaults:e,inherits:r}},function(t,i,e){function r(t,i,e){this.chart=t,this.group=this.chart.paper.set(),this.symbol=e,this.connectedTo=[],this.symbolType=i.symbolType,this.flowstate=i.flowstate||"future",this.next_direction=i.next&&i.direction_next?i.direction_next:void 0,this.text=this.chart.paper.text(0,0,i.text),i.key&&(this.text.node.id=i.key+"t"),this.text.node.setAttribute("class",this.getAttr("class")+"t"),this.text.attr({"text-anchor":"start",x:this.getAttr("text-margin"),fill:this.getAttr("font-color"),"font-size":this.getAttr("font-size")});var r=this.getAttr("font"),s=this.getAttr("font-family"),o=this.getAttr("font-weight");r&&this.text.attr({font:r}),s&&this.text.attr({"font-family":s}),o&&this.text.attr({"font-weight":o}),i.link&&this.text.attr("href",i.link),i.target&&this.text.attr("target",i.target);var n=this.getAttr("maxWidth");if(n){for(var h=i.text.split(" "),a="",x=0,y=h.length;xn?"\n"+l:" "+l}this.text.attr("text",a.substring(1))}if(this.group.push(this.text),e){var g=this.getAttr("text-margin");e.attr({fill:this.getAttr("fill"),stroke:this.getAttr("element-color"),"stroke-width":this.getAttr("line-width"),width:this.text.getBBox().width+2*g,height:this.text.getBBox().height+2*g}),e.node.setAttribute("class",this.getAttr("class")),i.link&&e.attr("href",i.link),i.target&&e.attr("target",i.target),i.key&&(e.node.id=i.key),this.group.push(e),e.insertBefore(this.text),this.text.attr({y:e.getBBox().height/2}),this.initialize()}}var s=e(3),o=s.drawLine,n=s.checkLineIntersection;r.prototype.getAttr=function(t){if(this.chart){var i,e=this.chart.options?this.chart.options[t]:void 0,r=this.chart.options.symbols?this.chart.options.symbols[this.symbolType][t]:void 0;return this.chart.options.flowstate&&this.chart.options.flowstate[this.flowstate]&&(i=this.chart.options.flowstate[this.flowstate][t]),i||r||e}},r.prototype.initialize=function(){this.group.transform("t"+this.getAttr("line-width")+","+this.getAttr("line-width")),this.width=this.group.getBBox().width,this.height=this.group.getBBox().height},r.prototype.getCenter=function(){return{x:this.getX()+this.width/2,y:this.getY()+this.height/2}},r.prototype.getX=function(){return this.group.getBBox().x},r.prototype.getY=function(){return this.group.getBBox().y},r.prototype.shiftX=function(t){this.group.transform("t"+(this.getX()+t)+","+this.getY())},r.prototype.setX=function(t){this.group.transform("t"+t+","+this.getY())},r.prototype.shiftY=function(t){this.group.transform("t"+this.getX()+","+(this.getY()+t))},r.prototype.setY=function(t){this.group.transform("t"+this.getX()+","+t)},r.prototype.getTop=function(){var t=this.getY(),i=this.getX()+this.width/2;return{x:i,y:t}},r.prototype.getBottom=function(){var t=this.getY()+this.height,i=this.getX()+this.width/2;return{x:i,y:t}},r.prototype.getLeft=function(){var t=this.getY()+this.group.getBBox().height/2,i=this.getX();return{x:i,y:t}},r.prototype.getRight=function(){var t=this.getY()+this.group.getBBox().height/2,i=this.getX()+this.group.getBBox().width;return{x:i,y:t}},r.prototype.render=function(){if(this.next){var t=this.getAttr("line-length");if("right"===this.next_direction){var i=this.getRight();if(!this.next.isPositioned){this.next.setY(i.y-this.next.height/2),this.next.shiftX(this.group.getBBox().x+this.width+t);var e=this;!function s(){for(var i,r=!1,o=0,n=e.chart.symbols.length;oe.next.getCenter().y&&h<=e.next.width/2){r=!0;break}}r&&(e.next.setX(i.getX()+i.width+t),s())}(),this.next.isPositioned=!0,this.next.render()}}else{var r=this.getBottom();this.next.isPositioned||(this.next.shiftY(this.getY()+this.height+t),this.next.setX(r.x-this.next.width/2),this.next.isPositioned=!0,this.next.render())}}},r.prototype.renderLines=function(){this.next&&(this.next_direction?this.drawLineTo(this.next,"",this.next_direction):this.drawLineTo(this.next))},r.prototype.drawLineTo=function(t,i,e){this.connectedTo.indexOf(t)<0&&this.connectedTo.push(t);var r,s=this.getCenter().x,h=this.getCenter().y,a=this.getRight(),x=this.getBottom(),y=this.getLeft(),l=t.getCenter().x,g=t.getCenter().y,f=t.getTop(),p=t.getRight(),c=t.getLeft(),u=s===l,d=h===g,m=hg||this===t,v=s>l,w=sq?($=["L",Q.x+2*B,V],Y.splice(F+1,0,$),$=["C",Q.x+2*B,V,Q.x,V-4*B,Q.x-2*B,V],Y.splice(F+2,0,$),r.attr("path",Y)):($=["L",Q.x-2*B,V],Y.splice(F+1,0,$),$=["C",Q.x-2*B,V,Q.x,V-4*B,Q.x+2*B,V],Y.splice(F+2,0,$),r.attr("path",Y)):V>G?($=["L",N,Q.y+2*B],Y.splice(F+1,0,$),$=["C",N,Q.y+2*B,N+4*B,Q.y,N,Q.y-2*B],Y.splice(F+2,0,$),r.attr("path",Y)):($=["L",N,Q.y-2*B],Y.splice(F+1,0,$),$=["C",N,Q.y-2*B,N+4*B,Q.y,N,Q.y+2*B],Y.splice(F+2,0,$),r.attr("path",Y)),F+=2,O+=2}}}this.chart.lines.push(r)}(!this.chart.maxXFromLine||this.chart.maxXFromLine&&k>this.chart.maxXFromLine)&&(this.chart.maxXFromLine=k)},t.exports=r},function(t,i){function e(t,i,e){var r,s,o="M{0},{1}";for(r=2,s=2*e.length+2;rc.x?i.x-(i.x-c.x)/2:c.x-(c.x-i.x)/2,d=i.y>c.y?i.y-(i.y-c.y)/2:c.y-(c.y-i.y)/2,p?(u-=f.getBBox().width/2,d-=t.options["text-margin"]):(u+=t.options["text-margin"],d-=f.getBBox().height/2)):(u=i.x,d=i.y,p?(u+=t.options["text-margin"]/2,d-=t.options["text-margin"]):(u+=t.options["text-margin"]/2,d+=t.options["text-margin"])),f.attr({"text-anchor":"start","font-size":t.options["font-size"],fill:t.options["font-color"],x:u,y:d}),x&&f.attr({font:x}),y&&f.attr({"font-family":y}),l&&f.attr({"font-weight":l})}return a}function s(t,i,e,r,s,o,n,h){var a,x,y,l,g,f={x:null,y:null,onLine1:!1,onLine2:!1};return a=(h-o)*(e-t)-(n-s)*(r-i),0===a?f:(x=i-o,y=t-s,l=(n-s)*x-(h-o)*y,g=(e-t)*x-(r-i)*y,x=l/a,y=g/a,f.x=t+x*(e-t),f.y=i+x*(r-i),x>0&&x<1&&(f.onLine1=!0),y>0&&y<1&&(f.onLine2=!0),f)}t.exports={drawPath:e,drawLine:r,checkLineIntersection:s}},function(t,i,e){function r(t){function i(t){var i=t.indexOf("(")+1,e=t.indexOf(")");return i>=0&&e>=0?r.symbols[t.substring(0,i-1)]:r.symbols[t]}function e(t){var i="next",e=t.indexOf("(")+1,r=t.indexOf(")");return e>=0&&r>=0&&(i=X.substring(e,r),i.indexOf(",")<0&&"yes"!==i&&"no"!==i&&(i="next, "+i)),i}t=t||"",t=t.trim();for(var r={symbols:{},start:null,drawSVG:function(t,i){function e(t){if(g[t.key])return g[t.key];switch(t.symbolType){case"start":g[t.key]=new o(l,t);break;case"end":g[t.key]=new n(l,t);break;case"operation":g[t.key]=new h(l,t);break;case"inputoutput":g[t.key]=new a(l,t);break;case"subroutine":g[t.key]=new x(l,t);break;case"condition":g[t.key]=new y(l,t);break;default:return new Error("Wrong symbol type!")}return g[t.key]}var r=this;this.diagram&&this.diagram.clean();var l=new s(t,i);this.diagram=l;var g={};!function f(t,i,s){var o=e(t);return r.start===t?l.startWith(o):i&&s&&!i.pathOk&&(i instanceof y?(s.yes===t&&i.yes(o),s.no===t&&i.no(o)):i.then(o)),o.pathOk?o:(o instanceof y?(t.yes&&f(t.yes,o,t),t.no&&f(t.no,o,t)):t.next&&f(t.next,o,t),o)}(this.start),l.render()},clean:function(){this.diagram.clean()}},l=[],g=0,f=1,p=t.length;f")<0&&m.indexOf("=>")<0?(l[u-1]+="\n"+m,l.splice(u,1),d--):u++}for(;l.length>0;){var b=l.splice(0,1)[0].trim();if(b.indexOf("=>")>=0){var v,w=b.split("=>"),k={key:w[0],symbolType:w[1],text:null,link:null,target:null,flowstate:null};if(k.symbolType.indexOf(": ")>=0&&(v=k.symbolType.split(": "),k.symbolType=v.shift(),k.text=v.join(": ")),k.text&&k.text.indexOf(":>")>=0?(v=k.text.split(":>"),k.text=v.shift(),k.link=v.join(":>")):k.symbolType.indexOf(":>")>=0&&(v=k.symbolType.split(":>"),k.symbolType=v.shift(),k.link=v.join(":>")),k.symbolType.indexOf("\n")>=0&&(k.symbolType=k.symbolType.split("\n")[0]),k.link){var _=k.link.indexOf("[")+1,B=k.link.indexOf("]");_>=0&&B>=0&&(k.target=k.link.substring(_,B),k.link=k.link.substring(0,_-1))}if(k.text&&k.text.indexOf("|")>=0){var A=k.text.split("|");k.flowstate=A.pop().trim(),k.text=A.join("|")}r.symbols[k.key]=k}else if(b.indexOf("->")>=0)for(var L=b.split("->"),M=0,O=L.length;M=0){var S=Y.split(",");Y=S[0],C=S[1].trim()}if(r.start||(r.start=T),M+1r.right_symbol.getCenter().y&&h<=r.right_symbol.width/2){e=!0;break}}e&&(r.right_symbol.setX(i.getX()+i.width+t),s())}(),this.right_symbol.isPositioned=!0,this.right_symbol.render()}}},r.prototype.renderLines=function(){this.yes_symbol&&this.drawLineTo(this.yes_symbol,this.getAttr("yes-text"),this.yes_direction),this.no_symbol&&this.drawLineTo(this.no_symbol,this.getAttr("no-text"),this.no_direction)},t.exports=r},function(t,i,e){function r(t,i){i=i||{},this.paper=new s(t),this.options=o(i,n),this.symbols=[],this.lines=[],this.start=null}var s=e(15),o=e(1).defaults,n=e(7),h=e(5);r.prototype.handle=function(t){this.symbols.indexOf(t)<=-1&&this.symbols.push(t);var i=this;return t instanceof h?(t.yes=function(e){return t.yes_symbol=e,t.no_symbol&&(t.pathOk=!0),i.handle(e)},t.no=function(e){return t.no_symbol=e,t.yes_symbol&&(t.pathOk=!0),i.handle(e)}):t.then=function(e){return t.next=e,t.pathOk=!0,i.handle(e)},t},r.prototype.startWith=function(t){return this.start=t,this.handle(t)},r.prototype.render=function(){var t,i,e=0,r=0,s=0,o=0,n=0,h=0,a=0,x=0;for(s=0,o=this.symbols.length;se&&(e=t.width),t.height>r&&(r=t.height);for(s=0,o=this.symbols.length;sn&&(n=y),l>h&&(h=l);for(s=0,o=this.lines.length;sn&&(n=g),f>h&&(h=f)}var p=this.options.scale,c=this.options["line-width"];a<0&&(a-=c),x<0&&(x-=c);var u=n+c-a,d=h+c-x;this.paper.setSize(u*p,d*p),this.paper.setViewBox(a,x,u,d,!0)},r.prototype.clean=function(){if(this.paper){var t=this.paper.canvas;t.parentNode.removeChild(t)}},t.exports=r},function(t,i){t.exports={x:0,y:0,"line-width":3,"line-length":50,"text-margin":10,"font-size":14,"font-color":"black","line-color":"black","element-color":"black",fill:"white","yes-text":"yes","no-text":"no","arrow-end":"block","class":"flowchart",scale:1,symbols:{start:{},end:{},condition:{},inputoutput:{},operation:{},subroutine:{}}}},function(t,i){Array.prototype.indexOf||(Array.prototype.indexOf=function(t){"use strict";if(null===this)throw new TypeError;var i=Object(this),e=i.length>>>0;if(0===e)return-1;var r=0;if(arguments.length>0&&(r=Number(arguments[1]),r!=r?r=0:0!==r&&r!=1/0&&r!=-(1/0)&&(r=(r>0||-1)*Math.floor(Math.abs(r)))),r>=e)return-1;for(var s=r>=0?r:Math.max(e-Math.abs(r),0);s>>0;if(0===e)return-1;var r=e;arguments.length>1&&(r=Number(arguments[1]),r!=r?r=0:0!==r&&r!=1/0&&r!=-(1/0)&&(r=(r>0||-1)*Math.floor(Math.abs(r))));for(var s=r>=0?Math.min(r,e-1):e-Math.abs(r);s>=0;s--)if(s in i&&i[s]===t)return s;return-1}),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")})},function(t,i,e){function r(t,i){var e=t.paper.rect(0,0,0,0,20);i=i||{},i.text=i.text||"End",s.call(this,t,i,e)}var s=e(2),o=e(1).inherits;o(r,s),t.exports=r},function(t,i,e){function r(t,i){i=i||{},s.call(this,t,i),this.textMargin=this.getAttr("text-margin"),this.text.attr({x:3*this.textMargin});var e=this.text.getBBox().width+4*this.textMargin,r=this.text.getBBox().height+2*this.textMargin,o=this.textMargin,n=r/2,a={x:o,y:n},x=[{x:o-this.textMargin,y:r},{x:o-this.textMargin+e,y:r},{x:o-this.textMargin+e+2*this.textMargin,y:0},{x:o-this.textMargin+2*this.textMargin,y:0},{x:o,y:n}],y=h(t,a,x);y.attr({stroke:this.getAttr("element-color"),"stroke-width":this.getAttr("line-width"),fill:this.getAttr("fill")}),i.link&&y.attr("href",i.link),i.target&&y.attr("target",i.target),i.key&&(y.node.id=i.key),y.node.setAttribute("class",this.getAttr("class")),this.text.attr({y:y.getBBox().height/2}),this.group.push(y),y.insertBefore(this.text),this.initialize()}var s=e(2),o=e(1).inherits,n=e(3),h=n.drawPath;o(r,s),r.prototype.getLeft=function(){var t=this.getY()+this.group.getBBox().height/2,i=this.getX()+this.textMargin;return{x:i,y:t}},r.prototype.getRight=function(){var t=this.getY()+this.group.getBBox().height/2,i=this.getX()+this.group.getBBox().width-this.textMargin;return{x:i,y:t}},t.exports=r},function(t,i,e){function r(t,i){var e=t.paper.rect(0,0,0,0);i=i||{},s.call(this,t,i,e)}var s=e(2),o=e(1).inherits;o(r,s),t.exports=r},function(t,i,e){function r(t,i){var e=t.paper.rect(0,0,0,0,20);i=i||{},i.text=i.text||"Start",s.call(this,t,i,e)}var s=e(2),o=e(1).inherits;o(r,s),t.exports=r},function(t,i,e){function r(t,i){var e=t.paper.rect(0,0,0,0);i=i||{},s.call(this,t,i,e),e.attr({width:this.text.getBBox().width+4*this.getAttr("text-margin")}),this.text.attr({x:2*this.getAttr("text-margin")});var r=t.paper.rect(0,0,0,0);r.attr({x:this.getAttr("text-margin"),stroke:this.getAttr("element-color"),"stroke-width":this.getAttr("line-width"),width:this.text.getBBox().width+2*this.getAttr("text-margin"),height:this.text.getBBox().height+2*this.getAttr("text-margin"),fill:this.getAttr("fill")}),i.key&&(r.node.id=i.key+"i");var o=this.getAttr("font"),n=this.getAttr("font-family"),h=this.getAttr("font-weight");o&&r.attr({font:o}),n&&r.attr({"font-family":n}),h&&r.attr({"font-weight":h}),i.link&&r.attr("href",i.link),i.target&&r.attr("target",i.target),this.group.push(r),r.insertBefore(this.text),this.initialize()}var s=e(2),o=e(1).inherits;o(r,s),t.exports=r},function(t,i,e){if("undefined"!=typeof jQuery){var r=e(4);!function(t){t.fn.flowChart=function(i){return this.each(function(){var e=t(this),s=r(e.text());e.html(""),s.drawSVG(this,i)})}}(jQuery)}},function(i,e){i.exports=t}])}); -//# sourceMappingURL=flowchart.min.js.map \ No newline at end of file diff --git a/src/utils/flowchart.js/raphael.min.js b/src/utils/flowchart.js/raphael.min.js deleted file mode 100644 index 2fb91046..00000000 --- a/src/utils/flowchart.js/raphael.min.js +++ /dev/null @@ -1,3 +0,0 @@ -!function t(e,r){"object"==typeof exports&&"object"==typeof module?module.exports=r():"function"==typeof define&&define.amd?define([],r):"object"==typeof exports?exports.Raphael=r():e.Raphael=r()}(this,function(){return function(t){function e(i){if(r[i])return r[i].exports;var n=r[i]={exports:{},id:i,loaded:!1};return t[i].call(n.exports,n,n.exports,e),n.loaded=!0,n.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var i,n;i=[r(1),r(3),r(4)],n=function(t){return t}.apply(e,i),!(void 0!==n&&(t.exports=n))},function(t,e,r){var i,n;i=[r(2)],n=function(t){function e(r){if(e.is(r,"function"))return w?r():t.on("raphael.DOMload",r);if(e.is(r,Q))return e._engine.create[z](e,r.splice(0,3+e.is(r[0],$))).add(r);var i=Array.prototype.slice.call(arguments,0);if(e.is(i[i.length-1],"function")){var n=i.pop();return w?n.call(e._engine.create[z](e,i)):t.on("raphael.DOMload",function(){n.call(e._engine.create[z](e,i))})}return e._engine.create[z](e,arguments)}function r(t){if("function"==typeof t||Object(t)!==t)return t;var e=new t.constructor;for(var i in t)t[A](i)&&(e[i]=r(t[i]));return e}function i(t,e){for(var r=0,i=t.length;r=1e3&&delete o[l.shift()],l.push(s),o[s]=t[z](e,a),r?r(o[s]):o[s])}return n}function a(){return this.hex}function s(t,e){for(var r=[],i=0,n=t.length;n-2*!e>i;i+=2){var a=[{x:+t[i-2],y:+t[i-1]},{x:+t[i],y:+t[i+1]},{x:+t[i+2],y:+t[i+3]},{x:+t[i+4],y:+t[i+5]}];e?i?n-4==i?a[3]={x:+t[0],y:+t[1]}:n-2==i&&(a[2]={x:+t[0],y:+t[1]},a[3]={x:+t[2],y:+t[3]}):a[0]={x:+t[n-2],y:+t[n-1]}:n-4==i?a[3]=a[2]:i||(a[0]={x:+t[i],y:+t[i+1]}),r.push(["C",(-a[0].x+6*a[1].x+a[2].x)/6,(-a[0].y+6*a[1].y+a[2].y)/6,(a[1].x+6*a[2].x-a[3].x)/6,(a[1].y+6*a[2].y-a[3].y)/6,a[2].x,a[2].y])}return r}function o(t,e,r,i,n){var a=-3*e+9*r-9*i+3*n,s=t*a+6*e-12*r+6*i;return t*s-3*e+3*r}function l(t,e,r,i,n,a,s,l,h){null==h&&(h=1),h=h>1?1:h<0?0:h;for(var u=h/2,c=12,f=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],p=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],d=0,g=0;gd;)c/=2,f+=(pW(n,s)||W(e,i)W(a,o))){var l=(t*i-e*r)*(n-s)-(t-r)*(n*o-a*s),h=(t*i-e*r)*(a-o)-(e-i)*(n*o-a*s),u=(t-r)*(a-o)-(e-i)*(n-s);if(u){var c=l/u,f=h/u,p=+c.toFixed(2),d=+f.toFixed(2);if(!(p<+G(t,r).toFixed(2)||p>+W(t,r).toFixed(2)||p<+G(n,s).toFixed(2)||p>+W(n,s).toFixed(2)||d<+G(e,i).toFixed(2)||d>+W(e,i).toFixed(2)||d<+G(a,o).toFixed(2)||d>+W(a,o).toFixed(2)))return{x:c,y:f}}}}function c(t,e){return p(t,e)}function f(t,e){return p(t,e,1)}function p(t,r,i){var n=e.bezierBBox(t),a=e.bezierBBox(r);if(!e.isBBoxIntersect(n,a))return i?0:[];for(var s=l.apply(0,t),o=l.apply(0,r),h=W(~~(s/5),1),c=W(~~(o/5),1),f=[],p=[],d={},g=i?0:[],v=0;v=0&&S<=1.001&&A>=0&&A<=1.001&&(i?g++:g.push({x:C.x,y:C.y,t1:G(S,1),t2:G(A,1)}))}}return g}function d(t,r,i){t=e._path2curve(t),r=e._path2curve(r);for(var n,a,s,o,l,h,u,c,f,d,g=i?0:[],v=0,x=t.length;vi)return i;for(;ra?r=n:i=n,n=(i-r)/2+r}return n}var h=3*e,u=3*(i-e)-h,c=1-h-u,f=3*r,p=3*(n-r)-f,d=1-f-p;return o(t,1/(200*a))}function m(t,e){var r=[],i={};if(this.ms=e,this.times=1,t){for(var n in t)t[A](n)&&(i[ht(n)]=t[n],r.push(ht(n)));r.sort(Bt)}this.anim=i,this.top=r[r.length-1],this.percents=r}function b(r,i,n,a,s,o){n=ht(n);var l,h,u,c=[],f,p,d,v=r.ms,x={},m={},b={};if(a)for(w=0,B=Ee.length;wa*r.top){n=r.percents[w],p=r.percents[w-1]||0,v=v/r.top*(n-p),f=r.percents[w+1],l=r.anim[n];break}a&&i.attr(r.anim[r.percents[w]])}if(l){if(h)h.initstatus=a,h.start=new Date-h.ms*a;else{for(var C in l)if(l[A](C)&&(pt[A](C)||i.paper.customAttributes[A](C)))switch(x[C]=i.attr(C),null==x[C]&&(x[C]=ft[C]),m[C]=l[C],pt[C]){case $:b[C]=(m[C]-x[C])/v;break;case"colour":x[C]=e.getRGB(x[C]);var S=e.getRGB(m[C]);b[C]={r:(S.r-x[C].r)/v,g:(S.g-x[C].g)/v,b:(S.b-x[C].b)/v};break;case"path":var T=Qt(x[C],m[C]),E=T[1];for(x[C]=T[0],b[C]=[],w=0,B=x[C].length;w',Lt=Nt.firstChild,Lt.style.behavior="url(#default#VML)",!Lt||"object"!=typeof Lt.adj)return e.type=R;Nt=null}e.svg=!(e.vml="VML"==e.type),e._Paper=M,e.fn=N=M.prototype=e.prototype,e._id=0,e.is=function(t,e){return e=O.call(e),"finite"==e?!at[A](+t):"array"==e?t instanceof Array:"null"==e&&null===t||e==typeof t&&null!==t||"object"==e&&t===Object(t)||"array"==e&&Array.isArray&&Array.isArray(t)||tt.call(t).slice(8,-1).toLowerCase()==e},e.angle=function(t,r,i,n,a,s){if(null==a){var o=t-i,l=r-n;return o||l?(180+180*Y.atan2(-l,-o)/U+360)%360:0}return e.angle(t,r,a,s)-e.angle(i,n,a,s)},e.rad=function(t){return t%360*U/180},e.deg=function(t){return Math.round(180*t/U%360*1e3)/1e3},e.snapTo=function(t,r,i){if(i=e.is(i,"finite")?i:10,e.is(t,Q)){for(var n=t.length;n--;)if(H(t[n]-r)<=i)return t[n]}else{t=+t;var a=r%t;if(at-i)return r-a+t}return r};var zt=e.createUUID=function(t,e){return function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(t,e).toUpperCase()}}(/[xy]/g,function(t){var e=16*Y.random()|0,r="x"==t?e:3&e|8;return r.toString(16)});e.setWindow=function(r){t("raphael.setWindow",e,T.win,r),T.win=r,T.doc=T.win.document,e._engine.initWin&&e._engine.initWin(T.win)};var Pt=function(t){if(e.vml){var r=/^\s+|\s+$/g,i;try{var a=new ActiveXObject("htmlfile");a.write(""),a.close(),i=a.body}catch(s){i=createPopup().document.body}var o=i.createTextRange();Pt=n(function(t){try{i.style.color=I(t).replace(r,R);var e=o.queryCommandValue("ForeColor");return e=(255&e)<<16|65280&e|(16711680&e)>>>16,"#"+("000000"+e.toString(16)).slice(-6)}catch(n){return"none"}})}else{var l=T.doc.createElement("i");l.title="Raphaël Colour Picker",l.style.display="none",T.doc.body.appendChild(l),Pt=n(function(t){return l.style.color=t,T.doc.defaultView.getComputedStyle(l,R).getPropertyValue("color")})}return Pt(t)},Ft=function(){return"hsb("+[this.h,this.s,this.b]+")"},Rt=function(){return"hsl("+[this.h,this.s,this.l]+")"},jt=function(){return this.hex},It=function(t,r,i){if(null==r&&e.is(t,"object")&&"r"in t&&"g"in t&&"b"in t&&(i=t.b,r=t.g,t=t.r),null==r&&e.is(t,Z)){var n=e.getRGB(t);t=n.r,r=n.g,i=n.b}return(t>1||r>1||i>1)&&(t/=255,r/=255,i/=255),[t,r,i]},qt=function(t,r,i,n){t*=255,r*=255,i*=255;var a={r:t,g:r,b:i,hex:e.rgb(t,r,i),toString:jt};return e.is(n,"finite")&&(a.opacity=n),a};e.color=function(t){var r;return e.is(t,"object")&&"h"in t&&"s"in t&&"b"in t?(r=e.hsb2rgb(t),t.r=r.r,t.g=r.g,t.b=r.b,t.hex=r.hex):e.is(t,"object")&&"h"in t&&"s"in t&&"l"in t?(r=e.hsl2rgb(t),t.r=r.r,t.g=r.g,t.b=r.b,t.hex=r.hex):(e.is(t,"string")&&(t=e.getRGB(t)),e.is(t,"object")&&"r"in t&&"g"in t&&"b"in t?(r=e.rgb2hsl(t),t.h=r.h,t.s=r.s,t.l=r.l,r=e.rgb2hsb(t),t.v=r.b):(t={hex:"none"},t.r=t.g=t.b=t.h=t.s=t.v=t.l=-1)),t.toString=jt,t},e.hsb2rgb=function(t,e,r,i){this.is(t,"object")&&"h"in t&&"s"in t&&"b"in t&&(r=t.b,e=t.s,i=t.o,t=t.h),t*=360;var n,a,s,o,l;return t=t%360/60,l=r*e,o=l*(1-H(t%2-1)),n=a=s=r-l,t=~~t,n+=[l,o,0,0,o,l][t],a+=[o,l,l,o,0,0][t],s+=[0,0,o,l,l,o][t],qt(n,a,s,i)},e.hsl2rgb=function(t,e,r,i){this.is(t,"object")&&"h"in t&&"s"in t&&"l"in t&&(r=t.l,e=t.s,t=t.h),(t>1||e>1||r>1)&&(t/=360,e/=100,r/=100),t*=360;var n,a,s,o,l;return t=t%360/60,l=2*e*(r<.5?r:1-r),o=l*(1-H(t%2-1)),n=a=s=r-l/2,t=~~t,n+=[l,o,0,0,o,l][t],a+=[o,l,l,o,0,0][t],s+=[0,0,o,l,l,o][t],qt(n,a,s,i)},e.rgb2hsb=function(t,e,r){r=It(t,e,r),t=r[0],e=r[1],r=r[2];var i,n,a,s;return a=W(t,e,r),s=a-G(t,e,r),i=0==s?null:a==t?(e-r)/s:a==e?(r-t)/s+2:(t-e)/s+4,i=(i+360)%6*60/360,n=0==s?0:s/a,{h:i,s:n,b:a,toString:Ft}},e.rgb2hsl=function(t,e,r){r=It(t,e,r),t=r[0],e=r[1],r=r[2];var i,n,a,s,o,l;return s=W(t,e,r),o=G(t,e,r),l=s-o,i=0==l?null:s==t?(e-r)/l:s==e?(r-t)/l+2:(t-e)/l+4,i=(i+360)%6*60/360,a=(s+o)/2,n=0==l?0:a<.5?l/(2*a):l/(2-2*a),{h:i,s:n,l:a,toString:Rt}},e._path2string=function(){return this.join(",").replace(xt,"$1")};var Dt=e._preload=function(t,e){var r=T.doc.createElement("img");r.style.cssText="position:absolute;left:-9999em;top:-9999em",r.onload=function(){e.call(this),this.onload=null,T.doc.body.removeChild(this)},r.onerror=function(){T.doc.body.removeChild(this)},T.doc.body.appendChild(r),r.src=t};e.getRGB=n(function(t){if(!t||(t=I(t)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:a};if("none"==t)return{r:-1,g:-1,b:-1,hex:"none",toString:a};!(vt[A](t.toLowerCase().substring(0,2))||"#"==t.charAt())&&(t=Pt(t));var r,i,n,s,o,l,h,u=t.match(nt);return u?(u[2]&&(s=ut(u[2].substring(5),16),n=ut(u[2].substring(3,5),16),i=ut(u[2].substring(1,3),16)),u[3]&&(s=ut((l=u[3].charAt(3))+l,16),n=ut((l=u[3].charAt(2))+l,16),i=ut((l=u[3].charAt(1))+l,16)),u[4]&&(h=u[4][q](gt),i=ht(h[0]),"%"==h[0].slice(-1)&&(i*=2.55),n=ht(h[1]),"%"==h[1].slice(-1)&&(n*=2.55),s=ht(h[2]),"%"==h[2].slice(-1)&&(s*=2.55),"rgba"==u[1].toLowerCase().slice(0,4)&&(o=ht(h[3])),h[3]&&"%"==h[3].slice(-1)&&(o/=100)),u[5]?(h=u[5][q](gt),i=ht(h[0]),"%"==h[0].slice(-1)&&(i*=2.55),n=ht(h[1]),"%"==h[1].slice(-1)&&(n*=2.55),s=ht(h[2]),"%"==h[2].slice(-1)&&(s*=2.55),("deg"==h[0].slice(-3)||"°"==h[0].slice(-1))&&(i/=360),"hsba"==u[1].toLowerCase().slice(0,4)&&(o=ht(h[3])),h[3]&&"%"==h[3].slice(-1)&&(o/=100),e.hsb2rgb(i,n,s,o)):u[6]?(h=u[6][q](gt),i=ht(h[0]),"%"==h[0].slice(-1)&&(i*=2.55),n=ht(h[1]),"%"==h[1].slice(-1)&&(n*=2.55),s=ht(h[2]),"%"==h[2].slice(-1)&&(s*=2.55),("deg"==h[0].slice(-3)||"°"==h[0].slice(-1))&&(i/=360),"hsla"==u[1].toLowerCase().slice(0,4)&&(o=ht(h[3])),h[3]&&"%"==h[3].slice(-1)&&(o/=100),e.hsl2rgb(i,n,s,o)):(u={r:i,g:n,b:s,toString:a},u.hex="#"+(16777216|s|n<<8|i<<16).toString(16).slice(1),e.is(o,"finite")&&(u.opacity=o),u)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:a}},e),e.hsb=n(function(t,r,i){return e.hsb2rgb(t,r,i).hex}),e.hsl=n(function(t,r,i){return e.hsl2rgb(t,r,i).hex}),e.rgb=n(function(t,e,r){function i(t){return t+.5|0}return"#"+(16777216|i(r)|i(e)<<8|i(t)<<16).toString(16).slice(1)}),e.getColor=function(t){var e=this.getColor.start=this.getColor.start||{h:0,s:1,b:t||.75},r=this.hsb2rgb(e.h,e.s,e.b);return e.h+=.075,e.h>1&&(e.h=0,e.s-=.2,e.s<=0&&(this.getColor.start={h:0,s:1,b:e.b})),r.hex},e.getColor.reset=function(){delete this.start},e.parsePathString=function(t){if(!t)return null;var r=Vt(t);if(r.arr)return Yt(r.arr);var i={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},n=[];return e.is(t,Q)&&e.is(t[0],Q)&&(n=Yt(t)),n.length||I(t).replace(yt,function(t,e,r){var a=[],s=e.toLowerCase();if(r.replace(bt,function(t,e){e&&a.push(+e)}),"m"==s&&a.length>2&&(n.push([e][P](a.splice(0,2))),s="l",e="m"==e?"l":"L"),"r"==s)n.push([e][P](a));else for(;a.length>=i[s]&&(n.push([e][P](a.splice(0,i[s]))),i[s]););}),n.toString=e._path2string,r.arr=Yt(n),n},e.parseTransformString=n(function(t){if(!t)return null;var r={r:3,s:4,t:2,m:6},i=[];return e.is(t,Q)&&e.is(t[0],Q)&&(i=Yt(t)),i.length||I(t).replace(mt,function(t,e,r){var n=[],a=O.call(e);r.replace(bt,function(t,e){e&&n.push(+e)}),i.push([e][P](n))}),i.toString=e._path2string,i});var Vt=function(t){var e=Vt.ps=Vt.ps||{};return e[t]?e[t].sleep=100:e[t]={sleep:100},setTimeout(function(){for(var r in e)e[A](r)&&r!=t&&(e[r].sleep--,!e[r].sleep&&delete e[r])}),e[t]};e.findDotsAtSegment=function(t,e,r,i,n,a,s,o,l){var h=1-l,u=X(h,3),c=X(h,2),f=l*l,p=f*l,d=u*t+3*c*l*r+3*h*l*l*n+p*s,g=u*e+3*c*l*i+3*h*l*l*a+p*o,v=t+2*l*(r-t)+f*(n-2*r+t),x=e+2*l*(i-e)+f*(a-2*i+e),y=r+2*l*(n-r)+f*(s-2*n+r),m=i+2*l*(a-i)+f*(o-2*a+i),b=h*t+l*r,_=h*e+l*i,w=h*n+l*s,k=h*a+l*o,B=90-180*Y.atan2(v-y,x-m)/U;return(v>y||x=t.x&&e<=t.x2&&r>=t.y&&r<=t.y2},e.isBBoxIntersect=function(t,r){var i=e.isPointInsideBBox;return i(r,t.x,t.y)||i(r,t.x2,t.y)||i(r,t.x,t.y2)||i(r,t.x2,t.y2)||i(t,r.x,r.y)||i(t,r.x2,r.y)||i(t,r.x,r.y2)||i(t,r.x2,r.y2)||(t.xr.x||r.xt.x)&&(t.yr.y||r.yt.y)},e.pathIntersection=function(t,e){return d(t,e)},e.pathIntersectionNumber=function(t,e){return d(t,e,1)},e.isPointInsidePath=function(t,r,i){var n=e.pathBBox(t);return e.isPointInsideBBox(n,r,i)&&d(t,[["M",r,i],["H",n.x2+10]],1)%2==1},e._removedFactory=function(e){return function(){t("raphael.log",null,"Raphaël: you are calling to method “"+e+"” of removed object",e)}};var Ot=e.pathBBox=function(t){var e=Vt(t);if(e.bbox)return r(e.bbox);if(!t)return{x:0,y:0,width:0,height:0,x2:0,y2:0};t=Qt(t);for(var i=0,n=0,a=[],s=[],o,l=0,h=t.length;l1&&(b=Y.sqrt(b),r=b*r,i=b*i);var _=r*r,w=i*i,k=(s==o?-1:1)*Y.sqrt(H((_*w-_*m*m-w*y*y)/(_*m*m+w*y*y))),B=k*r*m/i+(t+l)/2,C=k*-i*y/r+(e+h)/2,S=Y.asin(((e-C)/i).toFixed(9)),A=Y.asin(((h-C)/i).toFixed(9));S=tA&&(S-=2*U),!o&&A>S&&(A-=2*U)}var T=A-S;if(H(T)>c){var E=A,M=l,N=h;A=S+c*(o&&A>S?1:-1),l=B+r*Y.cos(A),h=C+i*Y.sin(A),p=Ut(l,h,r,i,a,0,o,M,N,[A,E,B,C])}T=A-S;var L=Y.cos(S),z=Y.sin(S),F=Y.cos(A),R=Y.sin(A),j=Y.tan(T/4),I=4/3*r*j,D=4/3*i*j,V=[t,e],O=[t+I*z,e-D*L],W=[l+I*R,h-D*F],G=[l,h];if(O[0]=2*V[0]-O[0],O[1]=2*V[1]-O[1],u)return[O,W,G][P](p);p=[O,W,G][P](p).join()[q](",");for(var X=[],$=0,Z=p.length;$"1e12"&&(c=.5),H(f)>"1e12"&&(f=.5),c>0&&c<1&&(g=$t(t,e,r,i,n,a,s,o,c),d.push(g.x),p.push(g.y)),f>0&&f<1&&(g=$t(t,e,r,i,n,a,s,o,f),d.push(g.x),p.push(g.y)),l=a-2*i+e-(o-2*a+i),h=2*(i-e)-2*(a-i),u=e-i,c=(-h+Y.sqrt(h*h-4*l*u))/2/l,f=(-h-Y.sqrt(h*h-4*l*u))/2/l,H(c)>"1e12"&&(c=.5),H(f)>"1e12"&&(f=.5),c>0&&c<1&&(g=$t(t,e,r,i,n,a,s,o,c),d.push(g.x),p.push(g.y)),f>0&&f<1&&(g=$t(t,e,r,i,n,a,s,o,f),d.push(g.x),p.push(g.y)),{min:{x:G[z](0,d),y:G[z](0,p)},max:{x:W[z](0,d),y:W[z](0,p)}}}),Qt=e._path2curve=n(function(t,e){var r=!e&&Vt(t);if(!e&&r.curve)return Yt(r.curve);for(var i=Gt(t),n=e&&Gt(e),a={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},s={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},o=(function(t,e,r){var i,n,a={T:1,Q:1};if(!t)return["C",e.x,e.y,e.x,e.y,e.x,e.y];switch(!(t[0]in a)&&(e.qx=e.qy=null),t[0]){case"M":e.X=t[1],e.Y=t[2];break;case"A":t=["C"][P](Ut[z](0,[e.x,e.y][P](t.slice(1))));break;case"S":"C"==r||"S"==r?(i=2*e.x-e.bx,n=2*e.y-e.by):(i=e.x,n=e.y),t=["C",i,n][P](t.slice(1));break;case"T":"Q"==r||"T"==r?(e.qx=2*e.x-e.qx,e.qy=2*e.y-e.qy):(e.qx=e.x,e.qy=e.y),t=["C"][P](Xt(e.x,e.y,e.qx,e.qy,t[1],t[2]));break;case"Q":e.qx=t[1],e.qy=t[2],t=["C"][P](Xt(e.x,e.y,t[1],t[2],t[3],t[4]));break;case"L":t=["C"][P](Ht(e.x,e.y,t[1],t[2]));break;case"H":t=["C"][P](Ht(e.x,e.y,t[1],e.y));break;case"V":t=["C"][P](Ht(e.x,e.y,e.x,t[1]));break;case"Z":t=["C"][P](Ht(e.x,e.y,e.X,e.Y))}return t}),l=function(t,e){if(t[e].length>7){t[e].shift();for(var r=t[e];r.length;)u[e]="A",n&&(c[e]="A"),t.splice(e++,0,["C"][P](r.splice(0,6)));t.splice(e,1),g=W(i.length,n&&n.length||0)}},h=function(t,e,r,a,s){t&&e&&"M"==t[s][0]&&"M"!=e[s][0]&&(e.splice(s,0,["M",a.x,a.y]),r.bx=0,r.by=0,r.x=t[s][1],r.y=t[s][2],g=W(i.length,n&&n.length||0))},u=[],c=[],f="",p="",d=0,g=W(i.length,n&&n.length||0);dn){if(r&&!c.start){if(f=ke(s,o,l[1],l[2],l[3],l[4],l[5],l[6],n-p),u+=["C"+f.start.x,f.start.y,f.m.x,f.m.y,f.x,f.y],a)return u;c.start=u,u=["M"+f.x,f.y+"C"+f.n.x,f.n.y,f.end.x,f.end.y,l[5],l[6]].join(),p+=h,s=+l[5],o=+l[6];continue}if(!t&&!r)return f=ke(s,o,l[1],l[2],l[3],l[4],l[5],l[6],n-p),{x:f.x,y:f.y,alpha:f.alpha}}p+=h,s=+l[5],o=+l[6]}u+=l.shift()+l}return c.end=u,f=t?p:r?c:e.findDotsAtSegment(s,o,l[0],l[1],l[2],l[3],l[4],l[5],1),f.alpha&&(f={x:f.x,y:f.y,alpha:f.alpha}),f}},Ce=Be(1),Se=Be(),Ae=Be(0,1);e.getTotalLength=Ce,e.getPointAtLength=Se,e.getSubpath=function(t,e,r){if(this.getTotalLength(t)-r<1e-6)return Ae(t,e).end;var i=Ae(t,r,1);return e?Ae(i,e).end:i},ye.getTotalLength=function(){var t=this.getPath();if(t)return this.node.getTotalLength?this.node.getTotalLength():Ce(t)},ye.getPointAtLength=function(t){var e=this.getPath();if(e)return Se(e,t)},ye.getPath=function(){var t,r=e._getPath[this.type];if("text"!=this.type&&"set"!=this.type)return r&&(t=r(this)),t},ye.getSubpath=function(t,r){var i=this.getPath();if(i)return e.getSubpath(i,t,r)};var Te=e.easing_formulas={linear:function(t){return t},"<":function(t){return X(t,1.7)},">":function(t){return X(t,.48)},"<>":function(t){var e=.48-t/1.04,r=Y.sqrt(.1734+e*e),i=r-e,n=X(H(i),1/3)*(i<0?-1:1),a=-r-e,s=X(H(a),1/3)*(a<0?-1:1),o=n+s+.5;return 3*(1-o)*o*o+o*o*o},backIn:function(t){var e=1.70158;return t*t*((e+1)*t-e)},backOut:function(t){t-=1;var e=1.70158;return t*t*((e+1)*t+e)+1},elastic:function(t){return t==!!t?t:X(2,-10*t)*Y.sin((t-.075)*(2*U)/.3)+1},bounce:function(t){var e=7.5625,r=2.75,i;return t<1/r?i=e*t*t:t<2/r?(t-=1.5/r,i=e*t*t+.75):t<2.5/r?(t-=2.25/r,i=e*t*t+.9375):(t-=2.625/r,i=e*t*t+.984375),i}};Te.easeIn=Te["ease-in"]=Te["<"],Te.easeOut=Te["ease-out"]=Te[">"],Te.easeInOut=Te["ease-in-out"]=Te["<>"],Te["back-in"]=Te.backIn,Te["back-out"]=Te.backOut;var Ee=[],Me=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){setTimeout(t,16)},Ne=function(){for(var r=+new Date,i=0;i1&&!n.next){for(v in u)u[A](v)&&(g[v]=n.totalOrigin[v]);n.el.attr(g),b(n.anim,n.el,n.anim.percents[0],null,n.totalOrigin,n.repeat-1)}n.next&&!n.stop&&b(n.anim,n.el,n.next,null,n.totalOrigin,n.repeat)}}}Ee.length&&Me(Ne)},Le=function(t){return t>255?255:t<0?0:t};ye.animateWith=function(t,r,i,n,a,s){var o=this;if(o.removed)return s&&s.call(o),o;var l=i instanceof m?i:e.animation(i,n,a,s),h,u;b(l,o,l.percents[0],null,o.attr());for(var c=0,f=Ee.length;cl&&(l=u)}l+="%",!t[l].callback&&(t[l].callback=n)}return new m(t,r)},ye.animate=function(t,r,i,n){var a=this;if(a.removed)return n&&n.call(a),a;var s=t instanceof m?t:e.animation(t,r,i,n);return b(s,a,s.percents[0],null,a.attr()),a},ye.setTime=function(t,e){return t&&null!=e&&this.status(t,G(e,t.ms)/t.ms),this},ye.status=function(t,e){var r=[],i=0,n,a;if(null!=e)return b(t,this,-1,G(e,1)),this;for(n=Ee.length;i1)for(var i=0,n=r.length;i.5)-1;l(f-.5,2)+l(p-.5,2)>.25&&(p=a.sqrt(.25-l(f-.5,2))*n+.5)&&.5!=p&&(p=p.toFixed(5)-1e-5*n)}return c}),n=n.split(/\s*\-\s*/),"linear"==h){var b=n.shift();if(b=-i(b),isNaN(b))return null;var _=[0,0,a.cos(t.rad(b)),a.sin(t.rad(b))],w=1/(s(o(_[2]),o(_[3]))||1);_[2]*=w,_[3]*=w,_[2]<0&&(_[0]=-_[2],_[2]=0),_[3]<0&&(_[1]=-_[3],_[3]=0)}var k=t._parseDots(n);if(!k)return null;if(u=u.replace(/[\(\)\s,\xb0#]/g,"_"),e.gradient&&u!=e.gradient.id&&(g.defs.removeChild(e.gradient),delete e.gradient),!e.gradient){y=v(h+"Gradient",{id:u}),e.gradient=y,v(y,"radial"==h?{fx:f,fy:p}:{x1:_[0],y1:_[1],x2:_[2],y2:_[3],gradientTransform:e.matrix.invert()}),g.defs.appendChild(y);for(var B=0,C=k.length;B1?z.opacity/100:z.opacity});case"stroke":z=t.getRGB(g),l.setAttribute(d,z.hex),"stroke"==d&&z[e]("opacity")&&v(l,{"stroke-opacity":z.opacity>1?z.opacity/100:z.opacity}),"stroke"==d&&i._.arrows&&("startString"in i._.arrows&&_(i,i._.arrows.startString),"endString"in i._.arrows&&_(i,i._.arrows.endString,1));break;case"gradient":("circle"==i.type||"ellipse"==i.type||"r"!=r(g).charAt())&&x(i,g);break;case"opacity":u.gradient&&!u[e]("stroke-opacity")&&v(l,{"stroke-opacity":g>1?g/100:g});case"fill-opacity":if(u.gradient){P=t._g.doc.getElementById(l.getAttribute("fill").replace(/^url\(#|\)$/g,c)),P&&(F=P.getElementsByTagName("stop"),v(F[F.length-1],{"stop-opacity":g}));break}default:"font-size"==d&&(g=n(g,10)+"px");var R=d.replace(/(\-.)/g,function(t){return t.substring(1).toUpperCase()});l.style[R]=g,i._.dirty=1,l.setAttribute(d,g)}}S(i,a),l.style.visibility=f},C=1.2,S=function(i,a){if("text"==i.type&&(a[e]("text")||a[e]("font")||a[e]("font-size")||a[e]("x")||a[e]("y"))){var s=i.attrs,o=i.node,l=o.firstChild?n(t._g.doc.defaultView.getComputedStyle(o.firstChild,c).getPropertyValue("font-size"),10):10;if(a[e]("text")){for(s.text=a.text;o.firstChild;)o.removeChild(o.firstChild);for(var h=r(a.text).split("\n"),u=[],f,p=0,d=h.length;p"));var Z=X.getBoundingClientRect();m.W=f.w=(Z.right-Z.left)/U,m.H=f.h=(Z.bottom-Z.top)/U,m.X=f.x,m.Y=f.y+m.H/2,("x"in l||"y"in l)&&(m.path.v=t.format("m{0},{1}l{2},{1}",a(f.x*b),a(f.y*b),a(f.x*b)+1));for(var Q=["x","y","text","font","font-family","font-weight","font-style","font-size"],J=0,K=Q.length;J.25&&(r=n.sqrt(.25-l(e-.5,2))*(2*(r>.5)-1)+.5),f=e+p+r),d}),a=a.split(/\s*\-\s*/),"linear"==c){var g=a.shift();if(g=-i(g),isNaN(g))return null}var v=t._parseDots(a);if(!v)return null;if(e=e.shape||e.node,v.length){e.removeChild(s),s.on=!0,s.method="none",s.color=v[0].color,s.color2=v[v.length-1].color;for(var x=[],y=0,m=v.length;y')}}catch(r){N=function(t){return e.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}},t._engine.initWin(t._g.win),t._engine.create=function(){var e=t._getContainer.apply(0,arguments),r=e.container,i=e.height,n,a=e.width,s=e.x,o=e.y;if(!r)throw new Error("VML container not found.");var l=new t._Paper,h=l.canvas=t._g.doc.createElement("div"),u=h.style;return s=s||0,o=o||0,a=a||512,i=i||342,l.width=a,l.height=i,a==+a&&(a+="px"),i==+i&&(i+="px"),l.coordsize=1e3*b+p+1e3*b,l.coordorigin="0 0",l.span=t._g.doc.createElement("span"),l.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",h.appendChild(l.span),u.cssText=t.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",a,i),1==r?(t._g.doc.body.appendChild(h),u.left=s+"px",u.top=o+"px",u.position="absolute"):r.firstChild?r.insertBefore(h,r.firstChild):r.appendChild(h),l.renderfix=function(){},l},t.prototype.clear=function(){t.eve("raphael.clear",this),this.canvas.innerHTML=d,this.span=t._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},t.prototype.remove=function(){t.eve("raphael.remove",this),this.canvas.parentNode.removeChild(this.canvas);for(var e in this)this[e]="function"==typeof this[e]?t._removedFactory(e):null;return!0};var L=t.st;for(var z in M)M[e](z)&&!L[e](z)&&(L[z]=function(t){return function(){var e=arguments;return this.forEach(function(r){r[t].apply(r,e)})}}(z))}}.apply(e,i),!(void 0!==n&&(t.exports=n))}])}); \ No newline at end of file diff --git a/src/utils/highlightjs/CHANGES.md b/src/utils/highlightjs/CHANGES.md deleted file mode 100644 index 05473a26..00000000 --- a/src/utils/highlightjs/CHANGES.md +++ /dev/null @@ -1,1646 +0,0 @@ -## Version 9.12.0 - -New language: - -- *MikroTik* RouterOS Scripting language by [Ivan Dementev][]. - -New style: - -- *VisualStudio 2015 Dark* by [Nicolas LLOBERA][] - -Improvements: - -- *Crystal* updated with new keywords and syntaxes by [Tsuyusato Kitsune][]. -- *Julia* updated to the modern definitions by [Alex Arslan][]. -- *julia-repl* added by [Morten Piibeleht][]. -- [Stanislav Belov][] wrote a new definition for *1C*, replacing the one that - has not been updated for more than 8 years. The new version supports syntax - for versions 7.7 and 8. -- [Nicolas LLOBERA][] improved C# definition fixing edge cases with function - titles detection and added highlighting of `[Attributes]`. -- [nnnik][] provided a few correctness fixes for *Autohotkey*. -- [Martin Clausen][] made annotation collections in *Clojure* to look - consistently with other kinds. -- [Alejandro Alonso][] updated *Swift* keywords. - -[Tsuyusato Kitsune]: https://github.com/MakeNowJust -[Alex Arslan]: https://github.com/ararslan -[Morten Piibeleht]: https://github.com/mortenpi -[Stanislav Belov]: https://github.com/4ppl -[Ivan Dementev]: https://github.com/DiVAN1x -[Nicolas LLOBERA]: https://github.com/Nicolas01 -[nnnik]: https://github.com/nnnik -[Martin Clausen]: https://github.com/maacl -[Alejandro Alonso]: https://github.com/Azoy - - -## Version 9.11.0 - -New languages: - -- *Shell* by [Tsuyusato Kitsune][] -- *jboss-cli* by [Raphaël Parrëe][] - -Improvements: - -- [Joël Porquet] has [greatly improved the definition of *makefile*][5b3e0e6]. -- *C++* class titles are now highlighted as in other languages with classes. -- [Jordi Petit][] added rarely used `or`, `and` and `not` keywords to *C++*. -- [Pieter Vantorre][] fixed highlighting of negative floating point values. - - -[Tsuyusato Kitsune]: https://github.com/MakeNowJust -[Jordi Petit]: https://github.com/jordi-petit -[Raphaël Parrëe]: https://github.com/rparree -[Pieter Vantorre]: https://github.com/NuclearCookie -[5b3e0e6]: https://github.com/isagalaev/highlight.js/commit/5b3e0e68bfaae282faff6697d6a490567fa9d44b - - -## Version 9.10.0 - -Apologies for missing the previous release cycle. Some thing just can't be -automated… Anyway, we're back! - -New languages: - -- *Hy* by [Sergey Sobko][] -- *Leaf* by [Hale Chan][] -- *N1QL* by [Andres Täht][] and [Rene Saarsoo][] - -Improvements: - -- *Rust* got updated with new keywords by [Kasper Andersen][] and then - significantly modernized even more by [Eduard-Mihai Burtescu][] (yes, @eddyb, - Rust core team member!) -- *Python* updated with f-literals by [Philipp A][]. -- *YAML* updated with unquoted strings support. -- *Gauss* updated with new keywords by [Matt Evans][]. -- *Lua* updated with new keywords by [Joe Blow][]. -- *Kotlin* updated with new keywords by [Philipp Hauer][]. -- *TypeScript* got highlighting of function params and updated keywords by - [Ike Ku][]. -- *Scheme* now correctly handles \`-quoted lists thanks to [Guannan Wei]. -- [Sam Wu][] fixed handling of `<<` in *C++* defines. - -[Philipp A]: https://github.com/flying-sheep -[Philipp Hauer]: https://github.com/phauer -[Sergey Sobko]: https://github.com/profitware -[Hale Chan]: https://github.com/halechan -[Matt Evans]: https://github.com/matthewevans -[Joe Blow]: https://github.com/mossarelli -[Kasper Andersen]: https://github.com/kasma1990 -[Eduard-Mihai Burtescu]: https://github.com/eddyb -[Andres Täht]: https://github.com/andrestaht -[Rene Saarsoo]: https://github.com/nene -[Philipp Hauer]: https://github.com/phauer -[Ike Ku]: https://github.com/dempfi -[Guannan Wei]: https://github.com/Kraks -[Sam Wu]: https://github.com/samsam2310 - - -## Version 9.9.0 - -New languages - -- *LLVM* by [Michael Rodler][] - -Improvements: - -- *TypeScript* updated with annotations and param lists inside constructors, by - [Raphael Parree][]. -- *CoffeeScript* updated with new keywords and fixed to recognize JavaScript - in \`\`\`, thanks to thanks to [Geoffrey Booth][]. -- Compiler directives in *Delphi* are now correctly highlighted as "meta". - -[Raphael Parree]: https://github.com/rparree -[Michael Rodler]: https://github.com/f0rki -[Geoffrey Booth]: https://github.com/GeoffreyBooth - - -## Version 9.8.0 "New York" - -This version is the second one that deserved a name. Because I'm in New York, -and the release isn't missing the deadline only because it's still Tuesday on -West Coast. - -New languages: - -- *Clean* by [Camil Staps][] -- *Flix* by [Magnus Madsen][] - -Improvements: - -- [Kenton Hamaluik][] did a comprehensive update for *Haxe*. -- New commands for *PowerShell* from [Nicolas Le Gall][]. -- [Jan T. Sott][] updated *NSIS*. -- *Java* and *Swift* support unicode characters in identifiers thanks to - [Alexander Lichter][]. - -[Camil Staps]: https://github.com/camilstaps -[Magnus Madsen]: https://github.com/magnus-madsen -[Kenton Hamaluik]: https://github.com/FuzzyWuzzie -[Nicolas Le Gall]: https://github.com/darkitty -[Jan T. Sott]: https://github.com/idleberg -[Alexander Lichter]: https://github.com/manniL - - -## Version 9.7.0 - -A comprehensive bugfix release. This is one of the best things about -highlight.js: even boring things keep getting better (even if slow). - -- VHDL updated with PSL keywords and uses more consistent styling. -- Nested C-style comments no longer break highlighting in many languages. -- JavaScript updated with `=>` functions, highlighted object attributes and - parsing within template string substitution blocks (`${...}`). -- Fixed another corner case with self-closing `` in JSX. -- Added `HEALTHCHECK` directive in Docker. -- Delphi updated with new Free Pascal keywords. -- Fixed digit separator parsing in C++. -- C# updated with new keywords and fixed to allow multiple identifiers within - generics `<...>`. -- Fixed another slow regex in Less. - - -## Version 9.6.0 - -New languages: - -- *ABNF* and *EBNF* by [Alex McKibben][] -- *Awk* by [Matthew Daly][] -- *SubUnit* by [Sergey Bronnikov][] - -New styles: - -- *Atom One* in both Dark and Light variants by [Daniel Gamage][] - -Plus, a few smaller updates for *Lasso*, *Elixir*, *C++* and *SQL*. - -[Alex McKibben]: https://github.com/mckibbenta -[Daniel Gamage]: https://github.com/danielgamage -[Matthew Daly]: https://github.com/matthewbdaly -[Sergey Bronnikov]: https://github.com/ligurio - - -## Version 9.5.0 - -New languages: - -- *Excel* by [Victor Zhou][] -- *Linden Scripting Language* by [Builder's Brewery][] -- *TAP* (Test Anything Protocol) by [Sergey Bronnikov][] -- *Pony* by [Joe Eli McIlvain][] -- *Coq* by [Stephan Boyer][] -- *dsconfig* and *LDIF* by [Jacob Childress][] - -New styles: - -- *Ocean Dark* by [Gavin Siu][] - -Notable changes: - -- [Minh Nguyễn][] added more built-ins to Objective C. -- [Jeremy Hull][] fixed corner cases in C++ preprocessor directives and Diff - comments. -- [Victor Zhou][] added support for digit separators in C++ numbers. - -[Gavin Siu]: https://github.com/gavsiu -[Builder's Brewery]: https://github.com/buildersbrewery -[Victor Zhou]: https://github.com/OiCMudkips -[Sergey Bronnikov]: https://github.com/ligurio -[Joe Eli McIlvain]: https://github.com/jemc -[Stephan Boyer]: https://github.com/boyers -[Jacob Childress]: https://github.com/braveulysses -[Minh Nguyễn]: https://github.com/1ec5 -[Jeremy Hull]: https://github.com/sourrust - - -## Version 9.4.0 - -New languages: - -- *PureBASIC* by [Tristano Ajmone][] -- *BNF* by [Oleg Efimov][] -- *Ada* by [Lars Schulna][] - -New styles: - -- *PureBASIC* by [Tristano Ajmone][] - -Improvements to existing languages and styles: - -- We now highlight function declarations in Go. -- [Taisuke Fujimoto][] contributed very convoluted rules for raw and - interpolated strings in C#. -- [Boone Severson][] updated Verilog to comply with IEEE 1800-2012 - SystemVerilog. -- [Victor Zhou][] improved rules for comments and strings in PowerShell files. -- [Janis Voigtländer][] updated the definition of Elm to version 0.17 of the - languages. Elm is now featured on the front page of . -- Special variable `$this` is highlighted as a keyword in PHP. -- `usize` and `isize` are now highlighted in Rust. -- Fixed labels and directives in x86 assembler. - -[Tristano Ajmone]: https://github.com/tajmone -[Taisuke Fujimoto]: https://github.com/temp-impl -[Oleg Efimov]: https://github.com/Sannis -[Boone Severson]: https://github.com/BooneJS -[Victor Zhou]: https://github.com/OiCMudkips -[Lars Schulna]: https://github.com/captain-hanuta -[Janis Voigtländer]: https://github.com/jvoigtlaender - - -## Version 9.3.0 - -New languages: - -- *Tagger Script* by [Philipp Wolfer][] -- *MoonScript* by [Billy Quith][] - -New styles: - -- *xt256* by [Herbert Shin][] - -Improvements to existing languages and styles: - -- More robust handling of unquoted HTML tag attributes -- Relevance tuning for QML which was unnecessary eager at seizing other - languages' code -- Improve GAMS language parsing -- Fixed a bunch of bugs around selectors in Less -- Kotlin's got a new definition for annotations, updated keywords and other - minor improvements -- Added `move` to Rust keywords -- Markdown now recognizes \`\`\`-fenced code blocks -- Improved detection of function declarations in C++ and C# - -[Philipp Wolfer]: https://github.com/phw -[Billy Quith]: https://github.com/billyquith -[Herbert Shin]: https://github.com/initbar - - -## Version 9.2.0 - -New languages: - -- *QML* by [John Foster][] -- *HTMLBars* by [Michael Johnston][] -- *CSP* by [Taras][] -- *Maxima* by [Robert Dodier][] - -New styles: - -- *Gruvbox* by [Qeole][] -- *Dracula* by [Denis Ciccale][] - -Improvements to existing languages and styles: - -- We now correctly handle JSX with arbitrary node tree depth. -- Argument list for `(lambda)` in Scheme is no longer highlighted as a function - call. -- Stylus syntax doesn't break on valid CSS. -- More correct handling of comments and strings and other improvements for - VimScript. -- More subtle work on the default style. -- We now use anonymous modules for AMD. -- `macro_rules!` is now recognized as a built-in in Rust. - -[John Foster]: https://github.com/jf990 -[Qeole]: https://github.com/Qeole -[Denis Ciccale]: https://github.com/dciccale -[Michael Johnston]: https://github.com/lastobelus -[Taras]: https://github.com/oxdef -[Robert Dodier]: https://github.com/robert-dodier - - -## Version 9.1.0 - -New languages: - -- *Stan* by [Brendan Rocks][] -- *BASIC* by [Raphaël Assénat][] -- *GAUSS* by [Matt Evans][] -- *DTS* by [Martin Braun][] -- *Arduino* by [Stefania Mellai][] - -New Styles: - -- *Arduino Light* by [Stefania Mellai][] - -Improvements to existing languages and styles: - -- Handle return type annotations in Python -- Allow shebang headers in Javascript -- Support strings in Rust meta -- Recognize `struct` as a class-level definition in Rust -- Recognize b-prefixed chars and strings in Rust -- Better numbers handling in Verilog - -[Brendan Rocks]: http://brendanrocks.com -[Raphaël Assénat]: https://github.com/raphnet -[Matt Evans]: https://github.com/matthewevans -[Martin Braun]: https://github.com/mbr0wn -[Stefania Mellai]: https://github.com/smellai - - -## Version 9.0.0 - -The new major version brings a reworked styling system. Highlight.js now defines -a limited set of highlightable classes giving a consistent result across all the -styles and languages. You can read a more detailed explanation and background in -the [tracking issue][#348] that started this long process back in May. - -This change is backwards incompatible for those who uses highlight.js with a -custom stylesheet. The [new style guide][sg] explains how to write styles -in this new world. - -Bundled themes have also suffered a significant amount of improvements and may -look different in places, but all the things now consistent and make more sense. -Among others, the Default style has got a refresh and will probably be tweaked -some more in next releases. Please do give your feedback in our -[issue tracker][issues]. - -New languages in this release: - -- *Caché Object Script* by [Nikita Savchenko][] -- *YAML* by [Stefan Wienert][] -- *MIPS Assembler* by [Nebuleon Fumika][] -- *HSP* by [prince][] - -Improvements to existing languages and styles: - -- ECMAScript 6 modules import now do not require closing semicolon. -- ECMAScript 6 classes constructors now highlighted. -- Template string support for Typescript, as for ECMAScript 6. -- Scala case classes params highlight fixed. -- Built-in names introduced in Julia v0.4 added by [Kenta Sato][]. -- Refreshed Default style. - -Other notable changes: - -- [Web workers support][webworkers] added bu [Jan Kühle][]. -- We now have tests for compressed browser builds as well. -- The building tool chain has been switched to node.js 4.x. and is now - shamelessly uses ES6 features all over the place, courtesy of [Jeremy Hull][]. -- License added to non-compressed browser build. - -[Jan Kühle]: https://github.com/frigus02 -[Stefan Wienert]: https://github.com/zealot128 -[Kenta Sato]: https://github.com/bicycle1885 -[Nikita Savchenko]: https://github.com/ZitRos -[webworkers]: https://github.com/isagalaev/highlight.js#web-workers -[Jeremy Hull]: https://github.com/sourrust -[#348]: https://github.com/isagalaev/highlight.js/issues/348 -[sg]: http://highlightjs.readthedocs.org/en/latest/style-guide.html -[issues]: https://github.com/isagalaev/highlight.js/issues -[Nebuleon Fumika]: https://github.com/Nebuleon -[prince]: https://github.com/prince-0203 - - -## Version 8.9.1 - -Some last-minute changes reverted due to strange bug with minified browser build: - -- Scala case classes params highlight fixed -- ECMAScript 6 modules import now do not require closing semicolon -- ECMAScript 6 classes constructors now highlighted -- Template string support for Typescript, as for ECMAScript 6 -- License added to not minified browser build - - -## Version 8.9.0 - -New languages: - -- *crmsh* by [Kristoffer Gronlund][] -- *SQF* by [Soren Enevoldsen][] - -[Kristoffer Gronlund]: https://github.com/krig -[Soren Enevoldsen]: https://github.com/senevoldsen90 - -Notable fixes and improvements to existing languages: - -- Added `abstract` and `namespace` keywords to TypeScript by [Daniel Rosenwasser][] -- Added `label` support to Dockerfile by [Ladislav Prskavec][] -- Crystal highlighting improved by [Tsuyusato Kitsune][] -- Missing Swift keywords added by [Nate Cook][] -- Improve detection of C block comments -- ~~Scala case classes params highlight fixed~~ -- ~~ECMAScript 6 modules import now do not require closing semicolon~~ -- ~~ECMAScript 6 classes constructors now highlighted~~ -- ~~Template string support for Typescript, as for ECMAScript 6~~ - -Other notable changes: - -- ~~License added to not minified browser build~~ - -[Kristoffer Gronlund]: https://github.com/krig -[Søren Enevoldsen]: https://github.com/senevoldsen90 -[Daniel Rosenwasser]: https://github.com/DanielRosenwasser -[Ladislav Prskavec]: https://github.com/abtris -[Tsuyusato Kitsune]: https://github.com/MakeNowJust -[Nate Cook]: https://github.com/natecook1000 - - -## Version 8.8.0 - -New languages: - -- *Golo* by [Philippe Charrière][] -- *GAMS* by [Stefan Bechert][] -- *IRPF90* by [Anthony Scemama][] -- *Access logs* by [Oleg Efimov][] -- *Crystal* by [Tsuyusato Kitsune][] - -Notable fixes and improvements to existing languages: - -- JavaScript highlighting no longer fails with ES6 default parameters -- Added keywords `async` and `await` to Python -- PHP heredoc support improved -- Allow preprocessor directives within C++ functions - -Other notable changes: - -- Change versions to X.Y.Z SemVer-compatible format -- Added ability to build all targets at once - -[Philippe Charrière]: https://github.com/k33g -[Stefan Bechert]: https://github.com/b-pos465 -[Anthony Scemama]: https://github.com/scemama -[Oleg Efimov]: https://github.com/Sannis -[Tsuyusato Kitsune]: https://github.com/MakeNowJust - - -## Version 8.7 - -New languages: - -- *Zephir* by [Oleg Efimov][] -- *Elm* by [Janis Voigtländer][] -- *XQuery* by [Dirk Kirsten][] -- *Mojolicious* by [Dotan Dimet][] -- *AutoIt* by Manh Tuan from [J2TeaM][] -- *Toml* (ini extension) by [Guillaume Gomez][] - -New styles: - -- *Hopscotch* by [Jan T. Sott][] -- *Grayscale* by [MY Sun][] - -Notable fixes and improvements to existing languages: - -- Fix encoding of images when copied over in certain builds -- Fix incorrect highlighting of the word "bug" in comments -- Treat decorators different from matrix multiplication in Python -- Fix traits inheritance highlighting in Rust -- Fix incorrect document -- Oracle keywords added to SQL language definition by [Vadimtro][] -- Postgres keywords added to SQL language definition by [Benjamin Auder][] -- Fix registers in x86asm being highlighted as a hex number -- Fix highlighting for numbers with a leading decimal point -- Correctly highlight numbers and strings inside of C/C++ macros -- C/C++ functions now support pointer, reference, and move returns - -[Oleg Efimov]: https://github.com/Sannis -[Guillaume Gomez]: https://github.com/GuillaumeGomez -[Janis Voigtländer]: https://github.com/jvoigtlaender -[Jan T. Sott]: https://github.com/idleberg -[Dirk Kirsten]: https://github.com/dirkk -[MY Sun]: https://github.com/simonmysun -[Vadimtro]: https://github.com/Vadimtro -[Benjamin Auder]: https://github.com/ghost -[Dotan Dimet]: https://github.com/dotandimet -[J2TeaM]: https://github.com/J2TeaM - - -## Version 8.6 - -New languages: - -- *C/AL* by [Kenneth Fuglsang][] -- *DNS zone file* by [Tim Schumacher][] -- *Ceylon* by [Lucas Werkmeister][] -- *OpenSCAD* by [Dan Panzarella][] -- *Inform7* by [Bruno Dias][] -- *armasm* by [Dan Panzarella][] -- *TP* by [Jay Strybis][] - -New styles: - -- *Atelier Cave*, *Atelier Estuary*, - *Atelier Plateau* and *Atelier Savanna* by [Bram de Haan][] -- *Github Gist* by [Louis Barranqueiro][] - -Notable fixes and improvements to existing languages: - -- Multi-line raw strings from C++11 are now supported -- Fix class names with dashes in HAML -- The `async` keyword from ES6/7 is now supported -- TypeScript functions handle type and parameter complexity better -- We unified phpdoc/javadoc/yardoc etc modes across all languages -- CSS .class selectors relevance was dropped to prevent wrong language detection -- Images is now included to CDN build -- Release process is now automated - -[Bram de Haan]: https://github.com/atelierbram -[Kenneth Fuglsang]: https://github.com/kfuglsang -[Louis Barranqueiro]: https://github.com/LouisBarranqueiro -[Tim Schumacher]: https://github.com/enko -[Lucas Werkmeister]: https://github.com/lucaswerkmeister -[Dan Panzarella]: https://github.com/pzl -[Bruno Dias]: https://github.com/sequitur -[Jay Strybis]: https://github.com/unreal - - -## Version 8.5 - -New languages: - -- *pf.conf* by [Peter Piwowarski][] -- *Julia* by [Kenta Sato][] -- *Prolog* by [Raivo Laanemets][] -- *Docker* by [Alexis Hénaut][] -- *Fortran* by [Anthony Scemama][] and [Thomas Applencourt][] -- *Kotlin* by [Sergey Mashkov][] - -New styles: - -- *Agate* by [Taufik Nurrohman][] -- *Darcula* by [JetBrains][] -- *Atelier Sulphurpool* by [Bram de Haan][] -- *Android Studio* by [Pedro Oliveira][] - -Notable fixes and improvements to existing languages: - -- ES6 features in JavaScript are better supported now by [Gu Yiling][]. -- Swift now recognizes body-less method definitions. -- Single expression functions `def foo, do: ... ` now work in Elixir. -- More uniform detection of built-in classes in Objective C. -- Fixes for number literals and processor directives in Rust. -- HTML ` - ``` - -- `tabReplace` and `useBR` that were used in different places are also unified - into the global options object and are to be set using `configure(options)`. - This function is documented in our [API docs][]. Also note that these - parameters are gone from `highlightBlock` and `fixMarkup` which are now also - rely on `configure`. - -- We removed public-facing (though undocumented) object `hljs.LANGUAGES` which - was used to register languages with the library in favor of two new methods: - `registerLanguage` and `getLanguage`. Both are documented in our [API docs][]. - -- Result returned from `highlight` and `highlightAuto` no longer contains two - separate attributes contributing to relevance score, `relevance` and - `keyword_count`. They are now unified in `relevance`. - -Another technically compatible change that nonetheless might need attention: - -- The structure of the NPM package was refactored, so if you had installed it - locally, you'll have to update your paths. The usual `require('highlight.js')` - works as before. This is contributed by [Dmitry Smolin][]. - -New features: - -- Languages now can be recognized by multiple names like "js" for JavaScript or - "html" for, well, HTML (which earlier insisted on calling it "xml"). These - aliases can be specified in the class attribute of the code container in your - HTML as well as in various API calls. For now there are only a few very common - aliases but we'll expand it in the future. All of them are listed in the - [class reference][cr]. - -- Language detection can now be restricted to a subset of languages relevant in - a given context — a web page or even a single highlighting call. This is - especially useful for node.js build that includes all the known languages. - Another example is a StackOverflow-style site where users specify languages - as tags rather than in the markdown-formatted code snippets. This is - documented in the [API reference][] (see methods `highlightAuto` and - `configure`). - -- Language definition syntax streamlined with [variants][] and - [beginKeywords][]. - -New languages and styles: - -- *Oxygene* by [Carlo Kok][] -- *Mathematica* by [Daniel Kvasnička][] -- *Autohotkey* by [Seongwon Lee][] -- *Atelier* family of styles in 10 variants by [Bram de Haan][] -- *Paraíso* styles by [Jan T. Sott][] - -Miscellaneous improvements: - -- Highlighting `=>` prompts in Clojure. -- [Jeremy Hull][] fixed a lot of styles for consistency. -- Finally, highlighting PHP and HTML [mixed in peculiar ways][php-html]. -- Objective C and C# now properly highlight titles in method definition. -- Big overhaul of relevance counting for a number of languages. Please do report - bugs about mis-detection of non-trivial code snippets! - -[API reference]: http://highlightjs.readthedocs.org/en/latest/api.html - -[cr]: http://highlightjs.readthedocs.org/en/latest/css-classes-reference.html -[api docs]: http://highlightjs.readthedocs.org/en/latest/api.html -[variants]: https://groups.google.com/d/topic/highlightjs/VoGC9-1p5vk/discussion -[beginKeywords]: https://github.com/isagalaev/highlight.js/commit/6c7fdea002eb3949577a85b3f7930137c7c3038d -[php-html]: https://twitter.com/highlightjs/status/408890903017689088 - -[Carlo Kok]: https://github.com/carlokok -[Bram de Haan]: https://github.com/atelierbram -[Daniel Kvasnička]: https://github.com/dkvasnicka -[Dmitry Smolin]: https://github.com/dimsmol -[Jeremy Hull]: https://github.com/sourrust -[Seongwon Lee]: https://github.com/dlimpid -[Jan T. Sott]: https://github.com/idleberg - - -## Version 7.5 - -A catch-up release dealing with some of the accumulated contributions. This one -is probably will be the last before the 8.0 which will be slightly backwards -incompatible regarding some advanced use-cases. - -One outstanding change in this version is the addition of 6 languages to the -[hosted script][d]: Markdown, ObjectiveC, CoffeeScript, Apache, Nginx and -Makefile. It now weighs about 6K more but we're going to keep it under 30K. - -New languages: - -- OCaml by [Mehdi Dogguy][mehdid] and [Nicolas Braud-Santoni][nbraud] -- [LiveCode Server][lcs] by [Ralf Bitter][revig] -- Scilab by [Sylvestre Ledru][sylvestre] -- basic support for Makefile by [Ivan Sagalaev][isagalaev] - -Improvements: - -- Ruby's got support for characters like `?A`, `?1`, `?\012` etc. and `%r{..}` - regexps. -- Clojure now allows a function call in the beginning of s-expressions - `(($filter "myCount") (arr 1 2 3 4 5))`. -- Haskell's got new keywords and now recognizes more things like pragmas, - preprocessors, modules, containers, FFIs etc. Thanks to [Zena Treep][treep] - for the implementation and to [Jeremy Hull][sourrust] for guiding it. -- Miscellaneous fixes in PHP, Brainfuck, SCSS, Asciidoc, CMake, Python and F#. - -[mehdid]: https://github.com/mehdid -[nbraud]: https://github.com/nbraud -[revig]: https://github.com/revig -[lcs]: http://livecode.com/developers/guides/server/ -[sylvestre]: https://github.com/sylvestre -[isagalaev]: https://github.com/isagalaev -[treep]: https://github.com/treep -[sourrust]: https://github.com/sourrust -[d]: http://highlightjs.org/download/ - - -## New core developers - -The latest long period of almost complete inactivity in the project coincided -with growing interest to it led to a decision that now seems completely obvious: -we need more core developers. - -So without further ado let me welcome to the core team two long-time -contributors: [Jeremy Hull][] and [Oleg -Efimov][]. - -Hope now we'll be able to work through stuff faster! - -P.S. The historical commit is [here][1] for the record. - -[Jeremy Hull]: https://github.com/sourrust -[Oleg Efimov]: https://github.com/sannis -[1]: https://github.com/isagalaev/highlight.js/commit/f3056941bda56d2b72276b97bc0dd5f230f2473f - - -## Version 7.4 - -This long overdue version is a snapshot of the current source tree with all the -changes that happened during the past year. Sorry for taking so long! - -Along with the changes in code highlight.js has finally got its new home at -, moving from its cradle on Software Maniacs which it -outgrew a long time ago. Be sure to report any bugs about the site to -. - -On to what's new… - -New languages: - -- Handlebars templates by [Robin Ward][] -- Oracle Rules Language by [Jason Jacobson][] -- F# by [Joans Follesø][] -- AsciiDoc and Haml by [Dan Allen][] -- Lasso by [Eric Knibbe][] -- SCSS by [Kurt Emch][] -- VB.NET by [Poren Chiang][] -- Mizar by [Kelley van Evert][] - -[Robin Ward]: https://github.com/eviltrout -[Jason Jacobson]: https://github.com/jayce7 -[Joans Follesø]: https://github.com/follesoe -[Dan Allen]: https://github.com/mojavelinux -[Eric Knibbe]: https://github.com/EricFromCanada -[Kurt Emch]: https://github.com/kemch -[Poren Chiang]: https://github.com/rschiang -[Kelley van Evert]: https://github.com/kelleyvanevert - -New style themes: - -- Monokai Sublime by [noformnocontent][] -- Railscasts by [Damien White][] -- Obsidian by [Alexander Marenin][] -- Docco by [Simon Madine][] -- Mono Blue by [Ivan Sagalaev][] (uses a single color hue for everything) -- Foundation by [Dan Allen][] - -[noformnocontent]: http://nn.mit-license.org/ -[Damien White]: https://github.com/visoft -[Alexander Marenin]: https://github.com/ioncreature -[Simon Madine]: https://github.com/thingsinjars -[Ivan Sagalaev]: https://github.com/isagalaev - -Other notable changes: - -- Corrected many corner cases in CSS. -- Dropped Python 2 version of the build tool. -- Implemented building for the AMD format. -- Updated Rust keywords (thanks to [Dmitry Medvinsky][]). -- Literal regexes can now be used in language definitions. -- CoffeeScript highlighting is now significantly more robust and rich due to - input from [Cédric Néhémie][]. - -[Dmitry Medvinsky]: https://github.com/dmedvinsky -[Cédric Néhémie]: https://github.com/abe33 - - -## Version 7.3 - -- Since this version highlight.js no longer works in IE version 8 and older. - It's made it possible to reduce the library size and dramatically improve code - readability and made it easier to maintain. Time to go forward! - -- New languages: AppleScript (by [Nathan Grigg][ng] and [Dr. Drang][dd]) and - Brainfuck (by [Evgeny Stepanischev][bolk]). - -- Improvements to existing languages: - - - interpreter prompt in Python (`>>>` and `...`) - - @-properties and classes in CoffeeScript - - E4X in JavaScript (by [Oleg Efimov][oe]) - - new keywords in Perl (by [Kirk Kimmel][kk]) - - big Ruby syntax update (by [Vasily Polovnyov][vast]) - - small fixes in Bash - -- Also Oleg Efimov did a great job of moving all the docs for language and style - developers and contributors from the old wiki under the source code in the - "docs" directory. Now these docs are nicely presented at - . - -[ng]: https://github.com/nathan11g -[dd]: https://github.com/drdrang -[bolk]: https://github.com/bolknote -[oe]: https://github.com/Sannis -[kk]: https://github.com/kimmel -[vast]: https://github.com/vast - - -## Version 7.2 - -A regular bug-fix release without any significant new features. Enjoy! - - -## Version 7.1 - -A Summer crop: - -- [Marc Fornos][mf] made the definition for Clojure along with the matching - style Rainbow (which, of course, works for other languages too). -- CoffeeScript support continues to improve getting support for regular - expressions. -- Yoshihide Jimbo ported to highlight.js [five Tomorrow styles][tm] from the - [project by Chris Kempson][tm0]. -- Thanks to [Casey Duncun][cd] the library can now be built in the popular - [AMD format][amd]. -- And last but not least, we've got a fair number of correctness and consistency - fixes, including a pretty significant refactoring of Ruby. - -[mf]: https://github.com/mfornos -[tm]: http://jmblog.github.com/color-themes-for-highlightjs/ -[tm0]: https://github.com/ChrisKempson/Tomorrow-Theme -[cd]: https://github.com/caseman -[amd]: http://requirejs.org/docs/whyamd.html - - -## Version 7.0 - -The reason for the new major version update is a global change of keyword syntax -which resulted in the library getting smaller once again. For example, the -hosted build is 2K less than at the previous version while supporting two new -languages. - -Notable changes: - -- The library now works not only in a browser but also with [node.js][]. It is - installable with `npm install highlight.js`. [API][] docs are available on our - wiki. - -- The new unique feature (apparently) among syntax highlighters is highlighting - *HTTP* headers and an arbitrary language in the request body. The most useful - languages here are *XML* and *JSON* both of which highlight.js does support. - Here's [the detailed post][p] about the feature. - -- Two new style themes: a dark "south" *[Pojoaque][]* by Jason Tate and an - emulation of*XCode* IDE by [Angel Olloqui][ao]. - -- Three new languages: *D* by [Aleksandar Ružičić][ar], *R* by [Joe Cheng][jc] - and *GLSL* by [Sergey Tikhomirov][st]. - -- *Nginx* syntax has become a million times smaller and more universal thanks to - remaking it in a more generic manner that doesn't require listing all the - directives in the known universe. - -- Function titles are now highlighted in *PHP*. - -- *Haskell* and *VHDL* were significantly reworked to be more rich and correct - by their respective maintainers [Jeremy Hull][sr] and [Igor Kalnitsky][ik]. - -And last but not least, many bugs have been fixed around correctness and -language detection. - -Overall highlight.js currently supports 51 languages and 20 style themes. - -[node.js]: http://nodejs.org/ -[api]: http://softwaremaniacs.org/wiki/doku.php/highlight.js:api -[p]: http://softwaremaniacs.org/blog/2012/05/10/http-and-json-in-highlight-js/en/ -[pojoaque]: http://web-cms-designs.com/ftopict-10-pojoaque-style-for-highlight-js-code-highlighter.html -[ao]: https://github.com/angelolloqui -[ar]: https://github.com/raleksandar -[jc]: https://github.com/jcheng5 -[st]: https://github.com/tikhomirov -[sr]: https://github.com/sourrust -[ik]: https://github.com/ikalnitsky - - -## Version 6.2 - -A lot of things happened in highlight.js since the last version! We've got nine -new contributors, the discussion group came alive, and the main branch on GitHub -now counts more than 350 followers. Here are most significant results coming -from all this activity: - -- 5 (five!) new languages: Rust, ActionScript, CoffeeScript, MatLab and - experimental support for markdown. Thanks go to [Andrey Vlasovskikh][av], - [Alexander Myadzel][am], [Dmytrii Nagirniak][dn], [Oleg Efimov][oe], [Denis - Bardadym][db] and [John Crepezzi][jc]. - -- 2 new style themes: Monokai by [Luigi Maselli][lm] and stylistic imitation of - another well-known highlighter Google Code Prettify by [Aahan Krish][ak]. - -- A vast number of [correctness fixes and code refactorings][log], mostly made - by [Oleg Efimov][oe] and [Evgeny Stepanischev][es]. - -[av]: https://github.com/vlasovskikh -[am]: https://github.com/myadzel -[dn]: https://github.com/dnagir -[oe]: https://github.com/Sannis -[db]: https://github.com/btd -[jc]: https://github.com/seejohnrun -[lm]: http://grigio.org/ -[ak]: https://github.com/geekpanth3r -[es]: https://github.com/bolknote -[log]: https://github.com/isagalaev/highlight.js/commits/ - - -## Version 6.1 — Solarized - -[Jeremy Hull][jh] has implemented my dream feature — a port of [Solarized][] -style theme famous for being based on the intricate color theory to achieve -correct contrast and color perception. It is now available for highlight.js in -both variants — light and dark. - -This version also adds a new original style Arta. Its author pumbur maintains a -[heavily modified fork of highlight.js][pb] on GitHub. - -[jh]: https://github.com/sourrust -[solarized]: http://ethanschoonover.com/solarized -[pb]: https://github.com/pumbur/highlight.js - - -## Version 6.0 - -New major version of the highlighter has been built on a significantly -refactored syntax. Due to this it's even smaller than the previous one while -supporting more languages! - -New languages are: - -- Haskell by [Jeremy Hull][sourrust] -- Erlang in two varieties — module and REPL — made collectively by [Nikolay - Zakharov][desh], [Dmitry Kovega][arhibot] and [Sergey Ignatov][ignatov] -- Objective C by [Valerii Hiora][vhbit] -- Vala by [Antono Vasiljev][antono] -- Go by [Stephan Kountso][steplg] - -[sourrust]: https://github.com/sourrust -[desh]: http://desh.su/ -[arhibot]: https://github.com/arhibot -[ignatov]: https://github.com/ignatov -[vhbit]: https://github.com/vhbit -[antono]: https://github.com/antono -[steplg]: https://github.com/steplg - -Also this version is marginally faster and fixes a number of small long-standing -bugs. - -Developer overview of the new language syntax is available in a [blog post about -recent beta release][beta]. - -[beta]: http://softwaremaniacs.org/blog/2011/04/25/highlight-js-60-beta/en/ - -P.S. New version is not yet available on a Yandex CDN, so for now you have to -download [your own copy][d]. - -[d]: /soft/highlight/en/download/ - - -## Version 5.14 - -Fixed bugs in HTML/XML detection and relevance introduced in previous -refactoring. - -Also test.html now shows the second best result of language detection by -relevance. - - -## Version 5.13 - -Past weekend began with a couple of simple additions for existing languages but -ended up in a big code refactoring bringing along nice improvements for language -developers. - -### For users - -- Description of C++ has got new keywords from the upcoming [C++ 0x][] standard. -- Description of HTML has got new tags from [HTML 5][]. -- CSS-styles have been unified to use consistent padding and also have lost - pop-outs with names of detected languages. -- [Igor Kalnitsky][ik] has sent two new language descriptions: CMake & VHDL. - -This makes total number of languages supported by highlight.js to reach 35. - -Bug fixes: - -- Custom classes on `
    ` tags are not being overridden anymore
    -- More correct highlighting of code blocks inside non-`
    ` containers:
    -  highlighter now doesn't insist on replacing them with its own container and
    -  just replaces the contents.
    -- Small fixes in browser compatibility and heuristics.
    -
    -[c++ 0x]: http://ru.wikipedia.org/wiki/C%2B%2B0x
    -[html 5]: http://en.wikipedia.org/wiki/HTML5
    -[ik]: http://kalnitsky.org.ua/
    -
    -### For developers
    -
    -The most significant change is the ability to include language submodes right
    -under `contains` instead of defining explicit named submodes in the main array:
    -
    -    contains: [
    -      'string',
    -      'number',
    -      {begin: '\\n', end: hljs.IMMEDIATE_RE}
    -    ]
    -
    -This is useful for auxiliary modes needed only in one place to define parsing.
    -Note that such modes often don't have `className` and hence won't generate a
    -separate `` in the resulting markup. This is similar in effect to
    -`noMarkup: true`. All existing languages have been refactored accordingly.
    -
    -Test file test.html has at last become a real test. Now it not only puts the
    -detected language name under the code snippet but also tests if it matches the
    -expected one. Test summary is displayed right above all language snippets.
    -
    -
    -## CDN
    -
    -Fine people at [Yandex][] agreed to host highlight.js on their big fast servers.
    -[Link up][l]!
    -
    -[yandex]: http://yandex.com/
    -[l]: http://softwaremaniacs.org/soft/highlight/en/download/
    -
    -
    -## Version 5.10 — "Paris".
    -
    -Though I'm on a vacation in Paris, I decided to release a new version with a
    -couple of small fixes:
    -
    -- Tomas Vitvar discovered that TAB replacement doesn't always work when used
    -  with custom markup in code
    -- SQL parsing is even more rigid now and doesn't step over SmallTalk in tests
    -
    -
    -## Version 5.9
    -
    -A long-awaited version is finally released.
    -
    -New languages:
    -
    -- Andrew Fedorov made a definition for Lua
    -- a long-time highlight.js contributor [Peter Leonov][pl] made a definition for
    -  Nginx config
    -- [Vladimir Moskva][vm] made a definition for TeX
    -
    -[pl]: http://kung-fu-tzu.ru/
    -[vm]: http://fulc.ru/
    -
    -Fixes for existing languages:
    -
    -- [Loren Segal][ls] reworked the Ruby definition and added highlighting for
    -  [YARD][] inline documentation
    -- the definition of SQL has become more solid and now it shouldn't be overly
    -  greedy when it comes to language detection
    -
    -[ls]: http://gnuu.org/
    -[yard]: http://yardoc.org/
    -
    -The highlighter has become more usable as a library allowing to do highlighting
    -from initialization code of JS frameworks and in ajax methods (see.
    -readme.eng.txt).
    -
    -Also this version drops support for the [WordPress][wp] plugin. Everyone is
    -welcome to [pick up its maintenance][p] if needed.
    -
    -[wp]: http://wordpress.org/
    -[p]: http://bazaar.launchpad.net/~isagalaev/+junk/highlight/annotate/342/src/wp_highlight.js.php
    -
    -
    -## Version 5.8
    -
    -- Jan Berkel has contributed a definition for Scala. +1 to hotness!
    -- All CSS-styles are rewritten to work only inside `
    ` tags to avoid
    -  conflicts with host site styles.
    -
    -
    -## Version 5.7.
    -
    -Fixed escaping of quotes in VBScript strings.
    -
    -
    -## Version 5.5
    -
    -This version brings a small change: now .ini-files allow digits, underscores and
    -square brackets in key names.
    -
    -
    -## Version 5.4
    -
    -Fixed small but upsetting bug in the packer which caused incorrect highlighting
    -of explicitly specified languages. Thanks to Andrew Fedorov for precise
    -diagnostics!
    -
    -
    -## Version 5.3
    -
    -The version to fulfil old promises.
    -
    -The most significant change is that highlight.js now preserves custom user
    -markup in code along with its own highlighting markup. This means that now it's
    -possible to use, say, links in code. Thanks to [Vladimir Dolzhenko][vd] for the
    -[initial proposal][1] and for making a proof-of-concept patch.
    -
    -Also in this version:
    -
    -- [Vasily Polovnyov][vp] has sent a GitHub-like style and has implemented
    -  support for CSS @-rules and Ruby symbols.
    -- Yura Zaripov has sent two styles: Brown Paper and School Book.
    -- Oleg Volchkov has sent a definition for [Parser 3][p3].
    -
    -[1]: http://softwaremaniacs.org/forum/highlightjs/6612/
    -[p3]: http://www.parser.ru/
    -[vp]: http://vasily.polovnyov.ru/
    -[vd]: http://dolzhenko.blogspot.com/
    -
    -
    -## Version 5.2
    -
    -- at last it's possible to replace indentation TABs with something sensible
    -  (e.g. 2 or 4 spaces)
    -- new keywords and built-ins for 1C by Sergey Baranov
    -- a couple of small fixes to Apache highlighting
    -
    -
    -## Version 5.1
    -
    -This is one of those nice version consisting entirely of new and shiny
    -contributions!
    -
    -- [Vladimir Ermakov][vooon] created highlighting for AVR Assembler
    -- [Ruslan Keba][rukeba] created highlighting for Apache config file. Also his
    -  original visual style for it is now available for all highlight.js languages
    -  under the name "Magula".
    -- [Shuen-Huei Guan][drake] (aka Drake) sent new keywords for RenderMan
    -  languages. Also thanks go to [Konstantin Evdokimenko][ke] for his advice on
    -  the matter.
    -
    -[vooon]: http://vehq.ru/about/
    -[rukeba]: http://rukeba.com/
    -[drake]: http://drakeguan.org/
    -[ke]: http://k-evdokimenko.moikrug.ru/
    -
    -
    -## Version 5.0
    -
    -The main change in the new major version of highlight.js is a mechanism for
    -packing several languages along with the library itself into a single compressed
    -file. Now sites using several languages will load considerably faster because
    -the library won't dynamically include additional files while loading.
    -
    -Also this version fixes a long-standing bug with Javascript highlighting that
    -couldn't distinguish between regular expressions and division operations.
    -
    -And as usually there were a couple of minor correctness fixes.
    -
    -Great thanks to all contributors! Keep using highlight.js.
    -
    -
    -## Version 4.3
    -
    -This version comes with two contributions from [Jason Diamond][jd]:
    -
    -- language definition for C# (yes! it was a long-missed thing!)
    -- Visual Studio-like highlighting style
    -
    -Plus there are a couple of minor bug fixes for parsing HTML and XML attributes.
    -
    -[jd]: http://jason.diamond.name/weblog/
    -
    -
    -## Version 4.2
    -
    -The biggest news is highlighting for Lisp, courtesy of Vasily Polovnyov. It's
    -somewhat experimental meaning that for highlighting "keywords" it doesn't use
    -any pre-defined set of a Lisp dialect. Instead it tries to highlight first word
    -in parentheses wherever it makes sense. I'd like to ask people programming in
    -Lisp to confirm if it's a good idea and send feedback to [the forum][f].
    -
    -Other changes:
    -
    -- Smalltalk was excluded from DEFAULT_LANGUAGES to save traffic
    -- [Vladimir Epifanov][voldmar] has implemented javascript style switcher for
    -  test.html
    -- comments now allowed inside Ruby function definition
    -- [MEL][] language from [Shuen-Huei Guan][drake]
    -- whitespace now allowed between `
    ` and ``
    -- better auto-detection of C++ and PHP
    -- HTML allows embedded VBScript (`<% .. %>`)
    -
    -[f]: http://softwaremaniacs.org/forum/highlightjs/
    -[voldmar]: http://voldmar.ya.ru/
    -[mel]: http://en.wikipedia.org/wiki/Maya_Embedded_Language
    -[drake]: http://drakeguan.org/
    -
    -
    -## Version 4.1
    -
    -Languages:
    -
    -- Bash from Vah
    -- DOS bat-files from Alexander Makarov (Sam)
    -- Diff files from Vasily Polovnyov
    -- Ini files from myself though initial idea was from Sam
    -
    -Styles:
    -
    -- Zenburn from Vladimir Epifanov, this is an imitation of a
    -  [well-known theme for Vim][zenburn].
    -- Ascetic from myself, as a realization of ideals of non-flashy highlighting:
    -  just one color in only three gradations :-)
    -
    -In other news. [One small bug][bug] was fixed, built-in keywords were added for
    -Python and C++ which improved auto-detection for the latter (it was shame that
    -[my wife's blog][alenacpp] had issues with it from time to time). And lastly
    -thanks go to Sam for getting rid of my stylistic comments in code that were
    -getting in the way of [JSMin][].
    -
    -[zenburn]: http://en.wikipedia.org/wiki/Zenburn
    -[alenacpp]: http://alenacpp.blogspot.com/
    -[bug]: http://softwaremaniacs.org/forum/viewtopic.php?id=1823
    -[jsmin]: http://code.google.com/p/jsmin-php/
    -
    -
    -## Version 4.0
    -
    -New major version is a result of vast refactoring and of many contributions.
    -
    -Visible new features:
    -
    -- Highlighting of embedded languages. Currently is implemented highlighting of
    -  Javascript and CSS inside HTML.
    -- Bundled 5 ready-made style themes!
    -
    -Invisible new features:
    -
    -- Highlight.js no longer pollutes global namespace. Only one object and one
    -  function for backward compatibility.
    -- Performance is further increased by about 15%.
    -
    -Changing of a major version number caused by a new format of language definition
    -files. If you use some third-party language files they should be updated.
    -
    -
    -## Version 3.5
    -
    -A very nice version in my opinion fixing a number of small bugs and slightly
    -increased speed in a couple of corner cases. Thanks to everybody who reports
    -bugs in he [forum][f] and by email!
    -
    -There is also a new language — XML. A custom XML formerly was detected as HTML
    -and didn't highlight custom tags. In this version I tried to make custom XML to
    -be detected and highlighted by its own rules. Which by the way include such
    -things as CDATA sections and processing instructions (``).
    -
    -[f]: http://softwaremaniacs.org/forum/viewforum.php?id=6
    -
    -
    -## Version 3.3
    -
    -[Vladimir Gubarkov][xonix] has provided an interesting and useful addition.
    -File export.html contains a little program that shows and allows to copy and
    -paste an HTML code generated by the highlighter for any code snippet. This can
    -be useful in situations when one can't use the script itself on a site.
    -
    -
    -[xonix]: http://xonixx.blogspot.com/
    -
    -
    -## Version 3.2 consists completely of contributions:
    -
    -- Vladimir Gubarkov has described SmallTalk
    -- Yuri Ivanov has described 1C
    -- Peter Leonov has packaged the highlighter as a Firefox extension
    -- Vladimir Ermakov has compiled a mod for phpBB
    -
    -Many thanks to you all!
    -
    -
    -## Version 3.1
    -
    -Three new languages are available: Django templates, SQL and Axapta. The latter
    -two are sent by [Dmitri Roudakov][1]. However I've almost entirely rewrote an
    -SQL definition but I'd never started it be it from the ground up :-)
    -
    -The engine itself has got a long awaited feature of grouping keywords
    -("keyword", "built-in function", "literal"). No more hacks!
    -
    -[1]: http://roudakov.ru/
    -
    -
    -## Version 3.0
    -
    -It is major mainly because now highlight.js has grown large and has become
    -modular. Now when you pass it a list of languages to highlight it will
    -dynamically load into a browser only those languages.
    -
    -Also:
    -
    -- Konstantin Evdokimenko of [RibKit][] project has created a highlighting for
    -  RenderMan Shading Language and RenderMan Interface Bytestream. Yay for more
    -  languages!
    -- Heuristics for C++ and HTML got better.
    -- I've implemented (at last) a correct handling of backslash escapes in C-like
    -  languages.
    -
    -There is also a small backwards incompatible change in the new version. The
    -function initHighlighting that was used to initialize highlighting instead of
    -initHighlightingOnLoad a long time ago no longer works. If you by chance still
    -use it — replace it with the new one.
    -
    -[RibKit]: http://ribkit.sourceforge.net/
    -
    -
    -## Version 2.9
    -
    -Highlight.js is a parser, not just a couple of regular expressions. That said
    -I'm glad to announce that in the new version 2.9 has support for:
    -
    -- in-string substitutions for Ruby -- `#{...}`
    -- strings from from numeric symbol codes (like #XX) for Delphi
    -
    -
    -## Version 2.8
    -
    -A maintenance release with more tuned heuristics. Fully backwards compatible.
    -
    -
    -## Version 2.7
    -
    -- Nikita Ledyaev presents highlighting for VBScript, yay!
    -- A couple of bugs with escaping in strings were fixed thanks to Mickle
    -- Ongoing tuning of heuristics
    -
    -Fixed bugs were rather unpleasant so I encourage everyone to upgrade!
    -
    -
    -## Version 2.4
    -
    -- Peter Leonov provides another improved highlighting for Perl
    -- Javascript gets a new kind of keywords — "literals". These are the words
    -  "true", "false" and "null"
    -
    -Also highlight.js homepage now lists sites that use the library. Feel free to
    -add your site by [dropping me a message][mail] until I find the time to build a
    -submit form.
    -
    -[mail]: mailto:Maniac@SoftwareManiacs.Org
    -
    -
    -## Version 2.3
    -
    -This version fixes IE breakage in previous version. My apologies to all who have
    -already downloaded that one!
    -
    -
    -## Version 2.2
    -
    -- added highlighting for Javascript
    -- at last fixed parsing of Delphi's escaped apostrophes in strings
    -- in Ruby fixed highlighting of keywords 'def' and 'class', same for 'sub' in
    -  Perl
    -
    -
    -## Version 2.0
    -
    -- Ruby support by [Anton Kovalyov][ak]
    -- speed increased by orders of magnitude due to new way of parsing
    -- this same way allows now correct highlighting of keywords in some tricky
    -  places (like keyword "End" at the end of Delphi classes)
    -
    -[ak]: http://anton.kovalyov.net/
    -
    -
    -## Version 1.0
    -
    -Version 1.0 of javascript syntax highlighter is released!
    -
    -It's the first version available with English description. Feel free to post
    -your comments and question to [highlight.js forum][forum]. And don't be afraid
    -if you find there some fancy Cyrillic letters -- it's for Russian users too :-)
    -
    -[forum]: http://softwaremaniacs.org/forum/viewforum.php?id=6
    diff --git a/src/utils/highlightjs/LICENSE b/src/utils/highlightjs/LICENSE
    deleted file mode 100644
    index 422deb73..00000000
    --- a/src/utils/highlightjs/LICENSE
    +++ /dev/null
    @@ -1,24 +0,0 @@
    -Copyright (c) 2006, Ivan Sagalaev
    -All rights reserved.
    -Redistribution and use in source and binary forms, with or without
    -modification, are permitted provided that the following conditions are met:
    -
    -    * Redistributions of source code must retain the above copyright
    -      notice, this list of conditions and the following disclaimer.
    -    * Redistributions in binary form must reproduce the above copyright
    -      notice, this list of conditions and the following disclaimer in the
    -      documentation and/or other materials provided with the distribution.
    -    * Neither the name of highlight.js nor the names of its contributors 
    -      may be used to endorse or promote products derived from this software 
    -      without specific prior written permission.
    -
    -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
    -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    -DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
    -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    diff --git a/src/utils/highlightjs/README.md b/src/utils/highlightjs/README.md
    deleted file mode 100644
    index 9f76e6bd..00000000
    --- a/src/utils/highlightjs/README.md
    +++ /dev/null
    @@ -1,150 +0,0 @@
    -# Highlight.js
    -
    -[![Build Status](https://travis-ci.org/isagalaev/highlight.js.svg?branch=master)](https://travis-ci.org/isagalaev/highlight.js)
    -
    -Highlight.js is a syntax highlighter written in JavaScript. It works in
    -the browser as well as on the server. It works with pretty much any
    -markup, doesn’t depend on any framework and has automatic language
    -detection.
    -
    -## Getting Started
    -
    -The bare minimum for using highlight.js on a web page is linking to the
    -library along with one of the styles and calling
    -[`initHighlightingOnLoad`][1]:
    -
    -```html
    -
    -
    -
    -```
    -
    -This will find and highlight code inside of `
    ` tags; it tries
    -to detect the language automatically. If automatic detection doesn’t
    -work for you, you can specify the language in the `class` attribute:
    -
    -```html
    -
    ...
    -``` - -The list of supported language classes is available in the [class -reference][2]. Classes can also be prefixed with either `language-` or -`lang-`. - -To disable highlighting altogether use the `nohighlight` class: - -```html -
    ...
    -``` - -## Custom Initialization - -When you need a bit more control over the initialization of -highlight.js, you can use the [`highlightBlock`][3] and [`configure`][4] -functions. This allows you to control *what* to highlight and *when*. - -Here’s an equivalent way to calling [`initHighlightingOnLoad`][1] using -jQuery: - -```javascript -$(document).ready(function() { - $('pre code').each(function(i, block) { - hljs.highlightBlock(block); - }); -}); -``` - -You can use any tags instead of `
    ` to mark up your code. If
    -you don't use a container that preserve line breaks you will need to
    -configure highlight.js to use the `
    ` tag: - -```javascript -hljs.configure({useBR: true}); - -$('div.code').each(function(i, block) { - hljs.highlightBlock(block); -}); -``` - -For other options refer to the documentation for [`configure`][4]. - - -## Web Workers - -You can run highlighting inside a web worker to avoid freezing the browser -window while dealing with very big chunks of code. - -In your main script: - -```javascript -addEventListener('load', function() { - var code = document.querySelector('#code'); - var worker = new Worker('worker.js'); - worker.onmessage = function(event) { code.innerHTML = event.data; } - worker.postMessage(code.textContent); -}) -``` - -In worker.js: - -```javascript -onmessage = function(event) { - importScripts('/highlight.pack.js'); - var result = self.hljs.highlightAuto(event.data); - postMessage(result.value); -} -``` - - -## Getting the Library - -You can get highlight.js as a hosted, or custom-build, browser script or -as a server module. Right out of the box the browser script supports -both AMD and CommonJS, so if you wish you can use RequireJS or -Browserify without having to build from source. The server module also -works perfectly fine with Browserify, but there is the option to use a -build specific to browsers rather than something meant for a server. -Head over to the [download page][5] for all the options. - -**Don't link to GitHub directly.** The library is not supposed to work straight -from the source, it requires building. If none of the pre-packaged options -work for you refer to the [building documentation][6]. - -**The CDN-hosted package doesn't have all the languages.** Otherwise it'd be -too big. If you don't see the language you need in the ["Common" section][5], -it can be added manually: - -```html - -``` - -**On Almond.** You need to use the optimizer to give the module a name. For -example: - -``` -r.js -o name=hljs paths.hljs=/path/to/highlight out=highlight.js -``` - - -## License - -Highlight.js is released under the BSD License. See [LICENSE][7] file -for details. - -## Links - -The official site for the library is at . - -Further in-depth documentation for the API and other topics is at -. - -Authors and contributors are listed in the [AUTHORS.en.txt][8] file. - -[1]: http://highlightjs.readthedocs.io/en/latest/api.html#inithighlightingonload -[2]: http://highlightjs.readthedocs.io/en/latest/css-classes-reference.html -[3]: http://highlightjs.readthedocs.io/en/latest/api.html#highlightblock-block -[4]: http://highlightjs.readthedocs.io/en/latest/api.html#configure-options -[5]: https://highlightjs.org/download/ -[6]: http://highlightjs.readthedocs.io/en/latest/building-testing.html -[7]: https://github.com/isagalaev/highlight.js/blob/master/LICENSE -[8]: https://github.com/isagalaev/highlight.js/blob/master/AUTHORS.en.txt diff --git a/src/utils/highlightjs/README.ru.md b/src/utils/highlightjs/README.ru.md deleted file mode 100644 index ac481d07..00000000 --- a/src/utils/highlightjs/README.ru.md +++ /dev/null @@ -1,142 +0,0 @@ -# Highlight.js - -Highlight.js — это инструмент для подсветки синтаксиса, написанный на JavaScript. Он работает -и в браузере, и на сервере. Он работает с практически любой HTML разметкой, не -зависит от каких-либо фреймворков и умеет автоматически определять язык. - - -## Начало работы - -Минимум, что нужно сделать для использования highlight.js на веб-странице — это -подключить библиотеку, CSS-стили и вызывать [`initHighlightingOnLoad`][1]: - -```html - - - -``` - -Библиотека найдёт и раскрасит код внутри тегов `
    `, попытавшись
    -автоматически определить язык. Когда автоопределение не срабатывает, можно явно
    -указать язык в атрибуте class:
    -
    -```html
    -
    ...
    -``` - -Список поддерживаемых классов языков доступен в [справочнике по классам][2]. -Класс также можно предварить префиксами `language-` или `lang-`. - -Чтобы отключить подсветку для какого-то блока, используйте класс `nohighlight`: - -```html -
    ...
    -``` - -## Инициализация вручную - -Чтобы иметь чуть больше контроля за инициализацией подсветки, вы можете -использовать функции [`highlightBlock`][3] и [`configure`][4]. Таким образом -можно управлять тем, *что* и *когда* подсвечивать. - -Вот пример инициализации, эквивалентной вызову [`initHighlightingOnLoad`][1], но -с использованием jQuery: - -```javascript -$(document).ready(function() { - $('pre code').each(function(i, block) { - hljs.highlightBlock(block); - }); -}); -``` - -Вы можете использовать любые теги разметки вместо `
    `. Если
    -используете контейнер, не сохраняющий переводы строк, вам нужно сказать
    -highlight.js использовать для них тег `
    `: - -```javascript -hljs.configure({useBR: true}); - -$('div.code').each(function(i, block) { - hljs.highlightBlock(block); -}); -``` - -Другие опции можно найти в документации функции [`configure`][4]. - - -## Web Workers - -Подсветку можно запустить внутри web worker'а, чтобы окно -браузера не подтормаживало при работе с большими кусками кода. - -В основном скрипте: - -```javascript -addEventListener('load', function() { - var code = document.querySelector('#code'); - var worker = new Worker('worker.js'); - worker.onmessage = function(event) { code.innerHTML = event.data; } - worker.postMessage(code.textContent); -}) -``` - -В worker.js: - -```javascript -onmessage = function(event) { - importScripts('/highlight.pack.js'); - var result = self.hljs.highlightAuto(event.data); - postMessage(result.value); -} -``` - - -## Установка библиотеки - -Highlight.js можно использовать в браузере прямо с CDN хостинга или скачать -индивидуальную сборку, а также установив модуль на сервере. На -[странице загрузки][5] подробно описаны все варианты. - -**Не подключайте GitHub напрямую.** Библиотека не предназначена для -использования в виде исходного кода, а требует отдельной сборки. Если вам не -подходит ни один из готовых вариантов, читайте [документацию по сборке][6]. - -**Файл на CDN содержит не все языки.** Иначе он будет слишком большого размера. -Если нужного вам языка нет в [категории "Common"][5], можно дообавить его -вручную: - -```html - -``` - -**Про Almond.** Нужно задать имя модуля в оптимизаторе, например: - -``` -r.js -o name=hljs paths.hljs=/path/to/highlight out=highlight.js -``` - - -## Лицензия - -Highlight.js распространяется под лицензией BSD. Подробнее читайте файл -[LICENSE][7]. - - -## Ссылки - -Официальный сайт билиотеки расположен по адресу . - -Более подробная документация по API и другим темам расположена на -. - -Авторы и контрибьюторы перечислены в файле [AUTHORS.ru.txt][8] file. - -[1]: http://highlightjs.readthedocs.io/en/latest/api.html#inithighlightingonload -[2]: http://highlightjs.readthedocs.io/en/latest/css-classes-reference.html -[3]: http://highlightjs.readthedocs.io/en/latest/api.html#highlightblock-block -[4]: http://highlightjs.readthedocs.io/en/latest/api.html#configure-options -[5]: https://highlightjs.org/download/ -[6]: http://highlightjs.readthedocs.io/en/latest/building-testing.html -[7]: https://github.com/isagalaev/highlight.js/blob/master/LICENSE -[8]: https://github.com/isagalaev/highlight.js/blob/master/AUTHORS.ru.txt diff --git a/src/utils/highlightjs/highlight.pack.js b/src/utils/highlightjs/highlight.pack.js deleted file mode 100644 index f933a3e9..00000000 --- a/src/utils/highlightjs/highlight.pack.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! highlight.js v9.12.0 | BSD3 License | git.io/hljslicense */ -!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&").replace(//g,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function u(e){s+=""}function c(e){("start"===e.event?o:u)(e.node)}for(var l=0,s="",f=[];e.length||r.length;){var g=i();if(s+=n(a.substring(l,g[0].offset)),l=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===l);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return s+n(a.substr(l))}function l(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):x(a.k).forEach(function(e){u(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return l("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var c=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=c.length?t(c.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function l(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function p(e,n,t,r){var a=r?"":I.classPrefix,i='',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=l(E,r),e?(B+=e[1],a+=p(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!y[E.sL])return n(k);var t=e?f(E.sL,k,!0,x[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(B+=t.r),e&&(x[E.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){L+=null!=E.sL?d():h(),k=""}function v(e){L+=e.cN?p(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(k+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),b(),t.rB||t.eB||(k=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),b(),a.eE&&(k=n));do E.cN&&(L+=C),E.skip||(B+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return k+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,E=i||N,x={},L="";for(R=E;R!==N;R=R.parent)R.cN&&(L=p(R.cN,"",!0)+L);var k="",B=0;try{for(var M,j,O=0;;){if(E.t.lastIndex=O,M=E.t.exec(t),!M)break;j=m(t.substring(O,M.index),M[0]),O=M.index+j}for(m(t.substr(O)),R=E;R.parent;R=R.parent)R.cN&&(L+=C);return{r:B,value:L,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function g(e,t){t=t||I.languages||x(y);var r={r:0,value:n(e)},a=r;return t.filter(w).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return I.tabReplace||I.useBR?e.replace(M,function(e,n){return I.useBR&&"\n"===e?"
    ":I.tabReplace?n.replace(/\t/g,I.tabReplace):""}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function d(e){var n,t,r,o,l,s=i(e);a(s)||(I.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,l=n.textContent,r=s?f(s,l,!0):g(l),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),l)),r.value=p(r.value),e.innerHTML=r.value,e.className=h(e.className,s,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){I=o(I,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,d)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=y[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function R(){return x(y)}function w(e){return e=(e||"").toLowerCase(),y[e]||y[L[e]]}var E=[],x=Object.keys,y={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="
    ",I={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=d,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("hy",function(e){var t={"builtin-name":"!= % %= & &= * ** **= *= *map + += , --build-class-- --import-- -= . / // //= /= < << <<= <= = > >= >> >>= @ @= ^ ^= abs accumulate all and any ap-compose ap-dotimes ap-each ap-each-while ap-filter ap-first ap-if ap-last ap-map ap-map-when ap-pipe ap-reduce ap-reject apply as-> ascii assert assoc bin break butlast callable calling-module-name car case cdr chain chr coll? combinations compile compress cond cons cons? continue count curry cut cycle dec def default-method defclass defmacro defmacro-alias defmacro/g! defmain defmethod defmulti defn defn-alias defnc defnr defreader defseq del delattr delete-route dict-comp dir disassemble dispatch-reader-macro distinct divmod do doto drop drop-last drop-while empty? end-sequence eval eval-and-compile eval-when-compile even? every? except exec filter first flatten float? fn fnc fnr for for* format fraction genexpr gensym get getattr global globals group-by hasattr hash hex id identity if if* if-not if-python2 import in inc input instance? integer integer-char? integer? interleave interpose is is-coll is-cons is-empty is-even is-every is-float is-instance is-integer is-integer-char is-iterable is-iterator is-keyword is-neg is-none is-not is-numeric is-odd is-pos is-string is-symbol is-zero isinstance islice issubclass iter iterable? iterate iterator? keyword keyword? lambda last len let lif lif-not list* list-comp locals loop macro-error macroexpand macroexpand-1 macroexpand-all map max merge-with method-decorator min multi-decorator multicombinations name neg? next none? nonlocal not not-in not? nth numeric? oct odd? open or ord partition permutations pos? post-route postwalk pow prewalk print product profile/calls profile/cpu put-route quasiquote quote raise range read read-str recursive-replace reduce remove repeat repeatedly repr require rest round route route-with-methods rwm second seq set-comp setattr setv some sorted string string? sum switch symbol? take take-nth take-while tee try unless unquote unquote-splicing vars walk when while with with* with-decorator with-gensyms xi xor yield yield-from zero? zip zip-longest | |= ~"},i="a-zA-Z_\\-!.?+*=<>&#'",a="["+i+"]["+i+"0-9/;:]*",r="[-+]?\\d+(\\.\\d+)?",o={cN:"meta",b:"^#!",e:"$"},s={b:a,r:0},n={cN:"number",b:r,r:0},l=e.inherit(e.QSM,{i:null}),c=e.C(";","$",{r:0}),d={cN:"literal",b:/\b([Tt]rue|[Ff]alse|nil|None)\b/},p={b:"[\\[\\{]",e:"[\\]\\}]"},m={cN:"comment",b:"\\^"+a},u=e.C("\\^\\{","\\}"),f={cN:"symbol",b:"[:]{1,2}"+a},h={b:"\\(",e:"\\)"},b={eW:!0,r:0},g={k:t,l:a,cN:"name",b:a,starts:b},y=[h,l,m,u,c,f,p,n,d,s];return h.c=[e.C("comment",""),g,b],b.c=y,p.c=y,{aliases:["hylang"],i:/\S/,c:[o,h,l,m,u,c,f,p,n,d]}});hljs.registerLanguage("perl",function(e){var t="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when",r={cN:"subst",b:"[$@]\\{",e:"\\}",k:t},s={b:"->{",e:"}"},n={v:[{b:/\$\d/},{b:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{b:/[\$%@][^\s\w{]/,r:0}]},i=[e.BE,r,n],o=[n,e.HCM,e.C("^\\=\\w","\\=cut",{eW:!0}),s,{cN:"string",c:i,v:[{b:"q[qwxr]?\\s*\\(",e:"\\)",r:5},{b:"q[qwxr]?\\s*\\[",e:"\\]",r:5},{b:"q[qwxr]?\\s*\\{",e:"\\}",r:5},{b:"q[qwxr]?\\s*\\|",e:"\\|",r:5},{b:"q[qwxr]?\\s*\\<",e:"\\>",r:5},{b:"qw\\s+q",e:"q",r:5},{b:"'",e:"'",c:[e.BE]},{b:'"',e:'"'},{b:"`",e:"`",c:[e.BE]},{b:"{\\w+}",c:[],r:0},{b:"-?\\w+\\s*\\=\\>",c:[],r:0}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\/\\/|"+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"function",bK:"sub",e:"(\\s*\\(.*?\\))?[;{]",eE:!0,r:5,c:[e.TM]},{b:"-\\w\\b",r:0},{b:"^__DATA__$",e:"^__END__$",sL:"mojolicious",c:[{b:"^@@.*",e:"$",cN:"comment"}]}];return r.c=o,s.c=o,{aliases:["pl","pm"],l:/[\w\.]+/,k:t,c:o}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0}]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("htmlbars",function(e){var a="action collection component concat debugger each each-in else get hash if input link-to loc log mut outlet partial query-params render textarea unbound unless with yield view",t={i:/\}\}/,b:/[a-zA-Z0-9_]+=/,rB:!0,r:0,c:[{cN:"attr",b:/[a-zA-Z0-9_]+/}]},i=({i:/\}\}/,b:/\)/,e:/\)/,c:[{b:/[a-zA-Z\.\-]+/,k:{built_in:a},starts:{eW:!0,r:0,c:[e.QSM]}}]},{eW:!0,r:0,k:{keyword:"as",built_in:a},c:[e.QSM,t,e.NM]});return{cI:!0,sL:"xml",c:[e.C("{{!(--)?","(--)?}}"),{cN:"template-tag",b:/\{\{[#\/]/,e:/\}\}/,c:[{cN:"name",b:/[a-zA-Z\.\-]+/,k:{"builtin-name":a},starts:i}]},{cN:"template-variable",b:/\{\{[a-zA-Z][a-zA-Z\-]+/,e:/\}\}/,k:{keyword:"as",built_in:a},c:[e.QSM]}]}});hljs.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"meta",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"comment",v:[{b:/Index: /,e:/$/},{b:/={3,}/,e:/$/},{b:/^\-{3}/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+{3}/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"addition",b:"^\\!",e:"$"}]}});hljs.registerLanguage("erlang",function(e){var r="[a-z'][a-zA-Z0-9_']*",c="("+r+":"+r+"|"+r+")",b={keyword:"after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun if let not of orelse|10 query receive rem try when xor",literal:"false true"},i=e.C("%","$"),n={cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},a={b:"fun\\s+"+r+"/\\d+"},d={b:c+"\\(",e:"\\)",rB:!0,r:0,c:[{b:c,r:0},{b:"\\(",e:"\\)",eW:!0,rE:!0,r:0}]},o={b:"{",e:"}",r:0},t={b:"\\b_([A-Z][A-Za-z0-9_]*)?",r:0},f={b:"[A-Z][a-zA-Z0-9_]*",r:0},l={b:"#"+e.UIR,r:0,rB:!0,c:[{b:"#"+e.UIR,r:0},{b:"{",e:"}",r:0}]},s={bK:"fun receive if try case",e:"end",k:b};s.c=[i,a,e.inherit(e.ASM,{cN:""}),s,d,e.QSM,n,o,t,f,l];var u=[i,a,s,d,e.QSM,n,o,t,f,l];d.c[1].c=u,o.c=u,l.c[1].c=u;var h={cN:"params",b:"\\(",e:"\\)",c:u};return{aliases:["erl"],k:b,i:"(",rB:!0,i:"\\(|#|//|/\\*|\\\\|:|;",c:[h,e.inherit(e.TM,{b:r})],starts:{e:";|\\.",k:b,c:u}},i,{b:"^-",e:"\\.",r:0,eE:!0,rB:!0,l:"-"+e.IR,k:"-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn -import -include -include_lib -compile -define -else -endif -file -behaviour -behavior -spec",c:[h]},n,e.QSM,l,t,f,o,{b:/\.$/}]}});hljs.registerLanguage("haxe",function(e){var t="Int Float String Bool Dynamic Void Array ";return{aliases:["hx"],k:{keyword:"break case cast catch continue default do dynamic else enum extern for function here if import in inline never new override package private get set public return static super switch this throw trace try typedef untyped using var while "+t,built_in:"trace this",literal:"true false null _"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"},{cN:"subst",b:"\\$",e:"\\W}"}]},e.QSM,e.CLCM,e.CBCM,e.CNM,{cN:"meta",b:"@:",e:"$"},{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elseif end error"}},{cN:"type",b:":[ ]*",e:"[^A-Za-z0-9_ \\->]",eB:!0,eE:!0,r:0},{cN:"type",b:":[ ]*",e:"\\W",eB:!0,eE:!0},{cN:"type",b:"new *",e:"\\W",eB:!0,eE:!0},{cN:"class",bK:"enum",e:"\\{",c:[e.TM]},{cN:"class",bK:"abstract",e:"[\\{$]",c:[{cN:"type",b:"\\(",e:"\\)",eB:!0,eE:!0},{cN:"type",b:"from +",e:"\\W",eB:!0,eE:!0},{cN:"type",b:"to +",e:"\\W",eB:!0,eE:!0},e.TM],k:{keyword:"abstract from to"}},{cN:"class",b:"\\b(class|interface) +",e:"[\\{$]",eE:!0,k:"class interface",c:[{cN:"keyword",b:"\\b(extends|implements) +",k:"extends implements",c:[{cN:"type",b:e.IR,r:0}]},e.TM]},{cN:"function",bK:"function",e:"\\(",eE:!0,i:"\\S",c:[e.TM]}],i:/<\//}});hljs.registerLanguage("gcode",function(N){var e="[A-Z_][A-Z0-9_.]*",c="\\%",E="IF DO WHILE ENDWHILE CALL ENDIF SUB ENDSUB GOTO REPEAT ENDREPEAT EQ LT GT NE GE LE OR XOR",i={cN:"meta",b:"([O])([0-9]+)"},n=[N.CLCM,N.CBCM,N.C(/\(/,/\)/),N.inherit(N.CNM,{b:"([-+]?([0-9]*\\.?[0-9]+\\.?))|"+N.CNR}),N.inherit(N.ASM,{i:null}),N.inherit(N.QSM,{i:null}),{cN:"name",b:"([G])([0-9]+\\.?[0-9]?)"},{cN:"name",b:"([M])([0-9]+\\.?[0-9]?)"},{cN:"attr",b:"(VC|VS|#)",e:"(\\d+)"},{cN:"attr",b:"(VZOFX|VZOFY|VZOFZ)"},{cN:"built_in",b:"(ATAN|ABS|ACOS|ASIN|SIN|COS|EXP|FIX|FUP|ROUND|LN|TAN)(\\[)",e:"([-+]?([0-9]*\\.?[0-9]+\\.?))(\\])"},{cN:"symbol",v:[{b:"N",e:"\\d+",i:"\\W"}]}];return{aliases:["nc"],cI:!0,l:e,k:E,c:[{cN:"meta",b:c},i].concat(n)}});hljs.registerLanguage("mizar",function(e){return{k:"environ vocabularies notations constructors definitions registrations theorems schemes requirements begin end definition registration cluster existence pred func defpred deffunc theorem proof let take assume then thus hence ex for st holds consider reconsider such that and in provided of as from be being by means equals implies iff redefine define now not or attr is mode suppose per cases set thesis contradiction scheme reserve struct correctness compatibility coherence symmetry assymetry reflexivity irreflexivity connectedness uniqueness commutativity idempotence involutiveness projectivity",c:[e.C("::","$")]}});hljs.registerLanguage("rust",function(e){var t="([ui](8|16|32|64|128|size)|f(32|64))?",r="alignof as be box break const continue crate do else enum extern false fn for if impl in let loop match mod mut offsetof once priv proc pub pure ref return self Self sizeof static struct super trait true type typeof unsafe unsized use virtual while where yield move default",n="drop i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 str char bool Box Option Result String Vec Copy Send Sized Sync Drop Fn FnMut FnOnce ToOwned Clone Debug PartialEq PartialOrd Eq Ord AsRef AsMut Into From Default Iterator Extend IntoIterator DoubleEndedIterator ExactSizeIterator SliceConcatExt ToString assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln! macro_rules! assert_ne! debug_assert_ne!";return{aliases:["rs"],k:{keyword:r,literal:"true false Some None Ok Err",built_in:n},l:e.IR+"!?",i:""}]}});hljs.registerLanguage("ebnf",function(a){var e=a.C(/\(\*/,/\*\)/),t={cN:"attribute",b:/^[ ]*[a-zA-Z][a-zA-Z-]*([\s-]+[a-zA-Z][a-zA-Z]*)*/},r={cN:"meta",b:/\?.*\?/},b={b:/=/,e:/;/,c:[e,r,a.ASM,a.QSM]};return{i:/\S/,c:[e,t,b]}});hljs.registerLanguage("ldif",function(e){return{c:[{cN:"attribute",b:"^dn",e:": ",eE:!0,starts:{e:"$",r:0},r:10},{cN:"attribute",b:"^\\w",e:": ",eE:!0,starts:{e:"$",r:0}},{cN:"literal",b:"^-",e:"$"},e.HCM]}});hljs.registerLanguage("swift",function(e){var i={keyword:"__COLUMN__ __FILE__ __FUNCTION__ __LINE__ as as! as? associativity break case catch class continue convenience default defer deinit didSet do dynamic dynamicType else enum extension fallthrough false fileprivate final for func get guard if import in indirect infix init inout internal is lazy left let mutating nil none nonmutating open operator optional override postfix precedence prefix private protocol Protocol public repeat required rethrows return right self Self set static struct subscript super switch throw throws true try try! try? Type typealias unowned var weak where while willSet",literal:"true false nil",built_in:"abs advance alignof alignofValue anyGenerator assert assertionFailure bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal fatalError filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare map max maxElement min minElement numericCast overlaps partition posix precondition preconditionFailure print println quickSort readLine reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith stride strideof strideofValue swap toString transcode underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers withUnsafePointer withUnsafePointers withVaList zip"},t={cN:"type",b:"\\b[A-Z][\\wÀ-ʸ']*",r:0},n=e.C("/\\*","\\*/",{c:["self"]}),r={cN:"subst",b:/\\\(/,e:"\\)",k:i,c:[]},a={cN:"number",b:"\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b",r:0},o=e.inherit(e.QSM,{c:[r,e.BE]});return r.c=[a],{k:i,c:[o,e.CLCM,n,t,a,{cN:"function",bK:"func",e:"{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{b://},{cN:"params",b:/\(/,e:/\)/,endsParent:!0,k:i,c:["self",a,o,e.CBCM,{b:":"}],i:/["']/}],i:/\[|%/},{cN:"class",bK:"struct protocol class extension enum",k:i,e:"\\{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/})]},{cN:"meta",b:"(@warn_unused_result|@exported|@lazy|@noescape|@NSCopying|@NSManaged|@objc|@convention|@required|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix|@autoclosure|@testable|@available|@nonobjc|@NSApplicationMain|@UIApplicationMain)"},{bK:"import",e:/$/,c:[e.CLCM,n]}]}});hljs.registerLanguage("smali",function(t){var s=["add","and","cmp","cmpg","cmpl","const","div","double","float","goto","if","int","long","move","mul","neg","new","nop","not","or","rem","return","shl","shr","sput","sub","throw","ushr","xor"],e=["aget","aput","array","check","execute","fill","filled","goto/16","goto/32","iget","instance","invoke","iput","monitor","packed","sget","sparse"],r=["transient","constructor","abstract","final","synthetic","public","private","protected","static","bridge","system"];return{aliases:["smali"],c:[{cN:"string",b:'"',e:'"',r:0},t.C("#","$",{r:0}),{cN:"keyword",v:[{b:"\\s*\\.end\\s[a-zA-Z0-9]*"},{b:"^[ ]*\\.[a-zA-Z]*",r:0},{b:"\\s:[a-zA-Z_0-9]*",r:0},{b:"\\s("+r.join("|")+")"}]},{cN:"built_in",v:[{b:"\\s("+s.join("|")+")\\s"},{b:"\\s("+s.join("|")+")((\\-|/)[a-zA-Z0-9]+)+\\s",r:10},{b:"\\s("+e.join("|")+")((\\-|/)[a-zA-Z0-9]+)*\\s",r:10}]},{cN:"class",b:"L[^(;:\n]*;",r:0},{b:"[vp][0-9]+"}]}});hljs.registerLanguage("cos",function(e){var t={cN:"string",v:[{b:'"',e:'"',c:[{b:'""',r:0}]}]},r={cN:"number",b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)",r:0},s="property parameter class classmethod clientmethod extends as break catch close continue do d|0 else elseif for goto halt hang h|0 if job j|0 kill k|0 lock l|0 merge new open quit q|0 read r|0 return set s|0 tcommit throw trollback try tstart use view while write w|0 xecute x|0 zkill znspace zn ztrap zwrite zw zzdump zzwrite print zbreak zinsert zload zprint zremove zsave zzprint mv mvcall mvcrt mvdim mvprint zquit zsync ascii";return{cI:!0,aliases:["cos","cls"],k:s,c:[r,t,e.CLCM,e.CBCM,{cN:"comment",b:/;/,e:"$",r:0},{cN:"built_in",b:/(?:\$\$?|\.\.)\^?[a-zA-Z]+/},{cN:"built_in",b:/\$\$\$[a-zA-Z]+/},{cN:"built_in",b:/%[a-z]+(?:\.[a-z]+)*/},{cN:"symbol",b:/\^%?[a-zA-Z][\w]*/},{cN:"keyword",b:/##class|##super|#define|#dim/},{b:/&sql\(/,e:/\)/,eB:!0,eE:!0,sL:"sql"},{b:/&(js|jscript|javascript)/,eB:!0,eE:!0,sL:"javascript"},{b:/&html<\s*\s*>/,sL:"xml"}]}});hljs.registerLanguage("nix",function(e){var r={keyword:"rec with let in inherit assert if else then",literal:"true false or and null",built_in:"import abort baseNameOf dirOf isNull builtins map removeAttrs throw toString derivation"},t={cN:"subst",b:/\$\{/,e:/}/,k:r},i={b:/[a-zA-Z0-9-_]+(\s*=)/,rB:!0,r:0,c:[{cN:"attr",b:/\S+/}]},s={cN:"string",c:[t],v:[{b:"''",e:"''"},{b:'"',e:'"'}]},a=[e.NM,e.HCM,e.CBCM,s,i];return t.c=a,{aliases:["nixos"],k:r,c:a}});hljs.registerLanguage("livescript",function(e){var t={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger case default function var with then unless until loop of by when and or is isnt not it that otherwise from to til fallthrough super case default function var void const let enum export import native __hasProp __extends __slice __bind __indexOf",literal:"true false null undefined yes no on off it that void",built_in:"npm require console print module global window document"},s="[A-Za-z$_](?:-[0-9A-Za-z$_]|[0-9A-Za-z$_])*",n=e.inherit(e.TM,{b:s}),i={cN:"subst",b:/#\{/,e:/}/,k:t},r={cN:"subst",b:/#[A-Za-z$_]/,e:/(?:\-[0-9A-Za-z$_]|[0-9A-Za-z$_])*/,k:t},c=[e.BNM,{cN:"number",b:"(\\b0[xX][a-fA-F0-9_]+)|(\\b\\d(\\d|_\\d)*(\\.(\\d(\\d|_\\d)*)?)?(_*[eE]([-+]\\d(_\\d|\\d)*)?)?[_a-z]*)",r:0,starts:{e:"(\\s*/)?",r:0}},{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,i,r]},{b:/"/,e:/"/,c:[e.BE,i,r]},{b:/\\/,e:/(\s|$)/,eE:!0}]},{cN:"regexp",v:[{b:"//",e:"//[gim]*",c:[i,e.HCM]},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{b:"@"+s},{b:"``",e:"``",eB:!0,eE:!0,sL:"javascript"}];i.c=c;var a={cN:"params",b:"\\(",rB:!0,c:[{b:/\(/,e:/\)/,k:t,c:["self"].concat(c)}]};return{aliases:["ls"],k:t,i:/\/\*/,c:c.concat([e.C("\\/\\*","\\*\\/"),e.HCM,{cN:"function",c:[n,a],rB:!0,v:[{b:"("+s+"\\s*(?:=|:=)\\s*)?(\\(.*\\))?\\s*\\B\\->\\*?",e:"\\->\\*?"},{b:"("+s+"\\s*(?:=|:=)\\s*)?!?(\\(.*\\))?\\s*\\B[-~]{1,2}>\\*?",e:"[-~]{1,2}>\\*?"},{b:"("+s+"\\s*(?:=|:=)\\s*)?(\\(.*\\))?\\s*\\B!?[-~]{1,2}>\\*?",e:"!?[-~]{1,2}>\\*?"}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[n]},n]},{b:s+":",e:":",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage("hsp",function(e){return{cI:!0,l:/[\w\._]+/,k:"goto gosub return break repeat loop continue wait await dim sdim foreach dimtype dup dupptr end stop newmod delmod mref run exgoto on mcall assert logmes newlab resume yield onexit onerror onkey onclick oncmd exist delete mkdir chdir dirlist bload bsave bcopy memfile if else poke wpoke lpoke getstr chdpm memexpand memcpy memset notesel noteadd notedel noteload notesave randomize noteunsel noteget split strrep setease button chgdisp exec dialog mmload mmplay mmstop mci pset pget syscolor mes print title pos circle cls font sysfont objsize picload color palcolor palette redraw width gsel gcopy gzoom gmode bmpsave hsvcolor getkey listbox chkbox combox input mesbox buffer screen bgscr mouse objsel groll line clrobj boxf objprm objmode stick grect grotate gsquare gradf objimage objskip objenable celload celdiv celput newcom querycom delcom cnvstow comres axobj winobj sendmsg comevent comevarg sarrayconv callfunc cnvwtos comevdisp libptr system hspstat hspver stat cnt err strsize looplev sublev iparam wparam lparam refstr refdval int rnd strlen length length2 length3 length4 vartype gettime peek wpeek lpeek varptr varuse noteinfo instr abs limit getease str strmid strf getpath strtrim sin cos tan atan sqrt double absf expf logf limitf powf geteasef mousex mousey mousew hwnd hinstance hdc ginfo objinfo dirinfo sysinfo thismod __hspver__ __hsp30__ __date__ __time__ __line__ __file__ _debug __hspdef__ and or xor not screen_normal screen_palette screen_hide screen_fixedsize screen_tool screen_frame gmode_gdi gmode_mem gmode_rgb0 gmode_alpha gmode_rgb0alpha gmode_add gmode_sub gmode_pixela ginfo_mx ginfo_my ginfo_act ginfo_sel ginfo_wx1 ginfo_wy1 ginfo_wx2 ginfo_wy2 ginfo_vx ginfo_vy ginfo_sizex ginfo_sizey ginfo_winx ginfo_winy ginfo_mesx ginfo_mesy ginfo_r ginfo_g ginfo_b ginfo_paluse ginfo_dispx ginfo_dispy ginfo_cx ginfo_cy ginfo_intid ginfo_newid ginfo_sx ginfo_sy objinfo_mode objinfo_bmscr objinfo_hwnd notemax notesize dir_cur dir_exe dir_win dir_sys dir_cmdline dir_desktop dir_mydoc dir_tv font_normal font_bold font_italic font_underline font_strikeout font_antialias objmode_normal objmode_guifont objmode_usefont gsquare_grad msgothic msmincho do until while wend for next _break _continue switch case default swbreak swend ddim ldim alloc m_pi rad2deg deg2rad ease_linear ease_quad_in ease_quad_out ease_quad_inout ease_cubic_in ease_cubic_out ease_cubic_inout ease_quartic_in ease_quartic_out ease_quartic_inout ease_bounce_in ease_bounce_out ease_bounce_inout ease_shake_in ease_shake_out ease_shake_inout ease_loop",c:[e.CLCM,e.CBCM,e.QSM,e.ASM,{cN:"string",b:'{"',e:'"}',c:[e.BE]},e.C(";","$",{r:0}),{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"addion cfunc cmd cmpopt comfunc const defcfunc deffunc define else endif enum epack func global if ifdef ifndef include modcfunc modfunc modinit modterm module pack packopt regcmd runtime undef usecom uselib"},c:[e.inherit(e.QSM,{cN:"meta-string"}),e.NM,e.CNM,e.CLCM,e.CBCM]},{cN:"symbol",b:"^\\*(\\w+|@)"},e.NM,e.CNM]}});hljs.registerLanguage("lisp",function(b){var e="[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*",c="\\|[^]*?\\|",r="(\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s|D|E|F|L|S)(\\+|\\-)?\\d+)?",a={cN:"meta",b:"^#!",e:"$"},l={cN:"literal",b:"\\b(t{1}|nil)\\b"},n={cN:"number",v:[{b:r,r:0},{b:"#(b|B)[0-1]+(/[0-1]+)?"},{b:"#(o|O)[0-7]+(/[0-7]+)?"},{b:"#(x|X)[0-9a-fA-F]+(/[0-9a-fA-F]+)?"},{b:"#(c|C)\\("+r+" +"+r,e:"\\)"}]},i=b.inherit(b.QSM,{i:null}),t=b.C(";","$",{r:0}),s={b:"\\*",e:"\\*"},u={cN:"symbol",b:"[:&]"+e},d={b:e,r:0},f={b:c},m={b:"\\(",e:"\\)",c:["self",l,i,n,d]},o={c:[n,i,s,u,m,d],v:[{b:"['`]\\(",e:"\\)"},{b:"\\(quote ",e:"\\)",k:{name:"quote"}},{b:"'"+c}]},v={v:[{b:"'"+e},{b:"#'"+e+"(::"+e+")*"}]},N={b:"\\(\\s*",e:"\\)"},A={eW:!0,r:0};return N.c=[{cN:"name",v:[{b:e},{b:c}]},A],A.c=[o,v,N,l,n,i,t,s,u,f,d],{i:/\S/,c:[n,a,l,i,t,o,v,N,d]}});hljs.registerLanguage("powershell",function(e){var t={b:"`[\\s\\S]",r:0},o={cN:"variable",v:[{b:/\$[\w\d][\w\d_:]*/}]},r={cN:"literal",b:/\$(null|true|false)\b/},n={cN:"string",v:[{b:/"/,e:/"/},{b:/@"/,e:/^"@/}],c:[t,o,{cN:"variable",b:/\$[A-z]/,e:/[^A-z]/}]},a={cN:"string",v:[{b:/'/,e:/'/},{b:/@'/,e:/^'@/}]},i={cN:"doctag",v:[{b:/\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/},{b:/\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\s+\S+/}]},s=e.inherit(e.C(null,null),{v:[{b:/#/,e:/$/},{b:/<#/,e:/#>/}],c:[i]});return{aliases:["ps"],l:/-?[A-z\.\-]+/,cI:!0,k:{keyword:"if else foreach return function do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch",built_in:"Add-Computer Add-Content Add-History Add-JobTrigger Add-Member Add-PSSnapin Add-Type Checkpoint-Computer Clear-Content Clear-EventLog Clear-History Clear-Host Clear-Item Clear-ItemProperty Clear-Variable Compare-Object Complete-Transaction Connect-PSSession Connect-WSMan Convert-Path ConvertFrom-Csv ConvertFrom-Json ConvertFrom-SecureString ConvertFrom-StringData ConvertTo-Csv ConvertTo-Html ConvertTo-Json ConvertTo-SecureString ConvertTo-Xml Copy-Item Copy-ItemProperty Debug-Process Disable-ComputerRestore Disable-JobTrigger Disable-PSBreakpoint Disable-PSRemoting Disable-PSSessionConfiguration Disable-WSManCredSSP Disconnect-PSSession Disconnect-WSMan Disable-ScheduledJob Enable-ComputerRestore Enable-JobTrigger Enable-PSBreakpoint Enable-PSRemoting Enable-PSSessionConfiguration Enable-ScheduledJob Enable-WSManCredSSP Enter-PSSession Exit-PSSession Export-Alias Export-Clixml Export-Console Export-Counter Export-Csv Export-FormatData Export-ModuleMember Export-PSSession ForEach-Object Format-Custom Format-List Format-Table Format-Wide Get-Acl Get-Alias Get-AuthenticodeSignature Get-ChildItem Get-Command Get-ComputerRestorePoint Get-Content Get-ControlPanelItem Get-Counter Get-Credential Get-Culture Get-Date Get-Event Get-EventLog Get-EventSubscriber Get-ExecutionPolicy Get-FormatData Get-Host Get-HotFix Get-Help Get-History Get-IseSnippet Get-Item Get-ItemProperty Get-Job Get-JobTrigger Get-Location Get-Member Get-Module Get-PfxCertificate Get-Process Get-PSBreakpoint Get-PSCallStack Get-PSDrive Get-PSProvider Get-PSSession Get-PSSessionConfiguration Get-PSSnapin Get-Random Get-ScheduledJob Get-ScheduledJobOption Get-Service Get-TraceSource Get-Transaction Get-TypeData Get-UICulture Get-Unique Get-Variable Get-Verb Get-WinEvent Get-WmiObject Get-WSManCredSSP Get-WSManInstance Group-Object Import-Alias Import-Clixml Import-Counter Import-Csv Import-IseSnippet Import-LocalizedData Import-PSSession Import-Module Invoke-AsWorkflow Invoke-Command Invoke-Expression Invoke-History Invoke-Item Invoke-RestMethod Invoke-WebRequest Invoke-WmiMethod Invoke-WSManAction Join-Path Limit-EventLog Measure-Command Measure-Object Move-Item Move-ItemProperty New-Alias New-Event New-EventLog New-IseSnippet New-Item New-ItemProperty New-JobTrigger New-Object New-Module New-ModuleManifest New-PSDrive New-PSSession New-PSSessionConfigurationFile New-PSSessionOption New-PSTransportOption New-PSWorkflowExecutionOption New-PSWorkflowSession New-ScheduledJobOption New-Service New-TimeSpan New-Variable New-WebServiceProxy New-WinEvent New-WSManInstance New-WSManSessionOption Out-Default Out-File Out-GridView Out-Host Out-Null Out-Printer Out-String Pop-Location Push-Location Read-Host Receive-Job Register-EngineEvent Register-ObjectEvent Register-PSSessionConfiguration Register-ScheduledJob Register-WmiEvent Remove-Computer Remove-Event Remove-EventLog Remove-Item Remove-ItemProperty Remove-Job Remove-JobTrigger Remove-Module Remove-PSBreakpoint Remove-PSDrive Remove-PSSession Remove-PSSnapin Remove-TypeData Remove-Variable Remove-WmiObject Remove-WSManInstance Rename-Computer Rename-Item Rename-ItemProperty Reset-ComputerMachinePassword Resolve-Path Restart-Computer Restart-Service Restore-Computer Resume-Job Resume-Service Save-Help Select-Object Select-String Select-Xml Send-MailMessage Set-Acl Set-Alias Set-AuthenticodeSignature Set-Content Set-Date Set-ExecutionPolicy Set-Item Set-ItemProperty Set-JobTrigger Set-Location Set-PSBreakpoint Set-PSDebug Set-PSSessionConfiguration Set-ScheduledJob Set-ScheduledJobOption Set-Service Set-StrictMode Set-TraceSource Set-Variable Set-WmiInstance Set-WSManInstance Set-WSManQuickConfig Show-Command Show-ControlPanelItem Show-EventLog Sort-Object Split-Path Start-Job Start-Process Start-Service Start-Sleep Start-Transaction Start-Transcript Stop-Computer Stop-Job Stop-Process Stop-Service Stop-Transcript Suspend-Job Suspend-Service Tee-Object Test-ComputerSecureChannel Test-Connection Test-ModuleManifest Test-Path Test-PSSessionConfigurationFile Trace-Command Unblock-File Undo-Transaction Unregister-Event Unregister-PSSessionConfiguration Unregister-ScheduledJob Update-FormatData Update-Help Update-List Update-TypeData Use-Transaction Wait-Event Wait-Job Wait-Process Where-Object Write-Debug Write-Error Write-EventLog Write-Host Write-Output Write-Progress Write-Verbose Write-Warning Add-MDTPersistentDrive Disable-MDTMonitorService Enable-MDTMonitorService Get-MDTDeploymentShareStatistics Get-MDTMonitorData Get-MDTOperatingSystemCatalog Get-MDTPersistentDrive Import-MDTApplication Import-MDTDriver Import-MDTOperatingSystem Import-MDTPackage Import-MDTTaskSequence New-MDTDatabase Remove-MDTMonitorData Remove-MDTPersistentDrive Restore-MDTPersistentDrive Set-MDTMonitorData Test-MDTDeploymentShare Test-MDTMonitorData Update-MDTDatabaseSchema Update-MDTDeploymentShare Update-MDTLinkedDS Update-MDTMedia Update-MDTMedia Add-VamtProductKey Export-VamtData Find-VamtManagedMachine Get-VamtConfirmationId Get-VamtProduct Get-VamtProductKey Import-VamtData Initialize-VamtData Install-VamtConfirmationId Install-VamtProductActivation Install-VamtProductKey Update-VamtProduct",nomarkup:"-ne -eq -lt -gt -ge -le -not -like -notlike -match -notmatch -contains -notcontains -in -notin -replace"},c:[t,e.NM,n,a,r,o,s]}});hljs.registerLanguage("inform7",function(e){var r="\\[",o="\\]";return{aliases:["i7"],cI:!0,k:{keyword:"thing room person man woman animal container supporter backdrop door scenery open closed locked inside gender is are say understand kind of rule"},c:[{cN:"string",b:'"',e:'"',r:0,c:[{cN:"subst",b:r,e:o}]},{cN:"section",b:/^(Volume|Book|Part|Chapter|Section|Table)\b/,e:"$"},{b:/^(Check|Carry out|Report|Instead of|To|Rule|When|Before|After)\b/,e:":",c:[{b:"\\(This",e:"\\)"}]},{cN:"comment",b:r,e:o,c:["self"]}]}});hljs.registerLanguage("subunit",function(s){var r={cN:"string",b:"\\[\n(multipart)?",e:"\\]\n"},t={cN:"string",b:"\\d{4}-\\d{2}-\\d{2}(\\s+)\\d{2}:\\d{2}:\\d{2}.\\d+Z"},e={cN:"string",b:"(\\+|-)\\d+"},c={cN:"keyword",r:10,v:[{b:"^(test|testing|success|successful|failure|error|skip|xfail|uxsuccess)(:?)\\s+(test)?"},{b:"^progress(:?)(\\s+)?(pop|push)?"},{b:"^tags:"},{b:"^time:"}]};return{cI:!0,c:[r,t,e,c]}});hljs.registerLanguage("cpp",function(t){var e={cN:"keyword",b:"\\b[a-z\\d_]*_t\\b"},r={cN:"string",v:[{b:'(u8?|U)?L?"',e:'"',i:"\\n",c:[t.BE]},{b:'(u8?|U)?R"',e:'"',c:[t.BE]},{b:"'\\\\?.",e:"'",i:"."}]},s={cN:"number",v:[{b:"\\b(0b[01']+)"},{b:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{b:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],r:0},i={cN:"meta",b:/#\s*[a-z]+\b/,e:/$/,k:{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef include"},c:[{b:/\\\n/,r:0},t.inherit(r,{cN:"meta-string"}),{cN:"meta-string",b:/<[^\n>]*>/,e:/$/,i:"\\n"},t.CLCM,t.CBCM]},a=t.IR+"\\s*\\(",c={keyword:"int float while private char catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and or not",built_in:"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr",literal:"true false nullptr NULL"},n=[e,t.CLCM,t.CBCM,s,r];return{aliases:["c","cc","h","c++","h++","hpp"],k:c,i:"",k:c,c:["self",e]},{b:t.IR+"::",k:c},{v:[{b:/=/,e:/;/},{b:/\(/,e:/\)/},{bK:"new throw return else",e:/;/}],k:c,c:n.concat([{b:/\(/,e:/\)/,k:c,c:n.concat(["self"]),r:0}]),r:0},{cN:"function",b:"("+t.IR+"[\\*&\\s]+)+"+a,rB:!0,e:/[{;=]/,eE:!0,k:c,i:/[^\w\s\*&]/,c:[{b:a,rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:c,r:0,c:[t.CLCM,t.CBCM,r,s,e]},t.CLCM,t.CBCM,i]},{cN:"class",bK:"class struct",e:/[{;:]/,c:[{b://,c:["self"]},t.TM]}]),exports:{preprocessor:i,strings:r,k:c}}});hljs.registerLanguage("arduino",function(e){var t=e.getLanguage("cpp").exports;return{k:{keyword:"boolean byte word string String array "+t.k.keyword,built_in:"setup loop while catch for if do goto try switch case else default break continue return KeyboardController MouseController SoftwareSerial EthernetServer EthernetClient LiquidCrystal RobotControl GSMVoiceCall EthernetUDP EsploraTFT HttpClient RobotMotor WiFiClient GSMScanner FileSystem Scheduler GSMServer YunClient YunServer IPAddress GSMClient GSMModem Keyboard Ethernet Console GSMBand Esplora Stepper Process WiFiUDP GSM_SMS Mailbox USBHost Firmata PImage Client Server GSMPIN FileIO Bridge Serial EEPROM Stream Mouse Audio Servo File Task GPRS WiFi Wire TFT GSM SPI SD runShellCommandAsynchronously analogWriteResolution retrieveCallingNumber printFirmwareVersion analogReadResolution sendDigitalPortPair noListenOnLocalhost readJoystickButton setFirmwareVersion readJoystickSwitch scrollDisplayRight getVoiceCallStatus scrollDisplayLeft writeMicroseconds delayMicroseconds beginTransmission getSignalStrength runAsynchronously getAsynchronously listenOnLocalhost getCurrentCarrier readAccelerometer messageAvailable sendDigitalPorts lineFollowConfig countryNameWrite runShellCommand readStringUntil rewindDirectory readTemperature setClockDivider readLightSensor endTransmission analogReference detachInterrupt countryNameRead attachInterrupt encryptionType readBytesUntil robotNameWrite readMicrophone robotNameRead cityNameWrite userNameWrite readJoystickY readJoystickX mouseReleased openNextFile scanNetworks noInterrupts digitalWrite beginSpeaker mousePressed isActionDone mouseDragged displayLogos noAutoscroll addParameter remoteNumber getModifiers keyboardRead userNameRead waitContinue processInput parseCommand printVersion readNetworks writeMessage blinkVersion cityNameRead readMessage setDataMode parsePacket isListening setBitOrder beginPacket isDirectory motorsWrite drawCompass digitalRead clearScreen serialEvent rightToLeft setTextSize leftToRight requestFrom keyReleased compassRead analogWrite interrupts WiFiServer disconnect playMelody parseFloat autoscroll getPINUsed setPINUsed setTimeout sendAnalog readSlider analogRead beginWrite createChar motorsStop keyPressed tempoWrite readButton subnetMask debugPrint macAddress writeGreen randomSeed attachGPRS readString sendString remotePort releaseAll mouseMoved background getXChange getYChange answerCall getResult voiceCall endPacket constrain getSocket writeJSON getButton available connected findUntil readBytes exitValue readGreen writeBlue startLoop IPAddress isPressed sendSysex pauseMode gatewayIP setCursor getOemKey tuneWrite noDisplay loadImage switchPIN onRequest onReceive changePIN playFile noBuffer parseInt overflow checkPIN knobRead beginTFT bitClear updateIR bitWrite position writeRGB highByte writeRed setSpeed readBlue noStroke remoteIP transfer shutdown hangCall beginSMS endWrite attached maintain noCursor checkReg checkPUK shiftOut isValid shiftIn pulseIn connect println localIP pinMode getIMEI display noBlink process getBand running beginSD drawBMP lowByte setBand release bitRead prepare pointTo readRed setMode noFill remove listen stroke detach attach noTone exists buffer height bitSet circle config cursor random IRread setDNS endSMS getKey micros millis begin print write ready flush width isPIN blink clear press mkdir rmdir close point yield image BSSID click delay read text move peek beep rect line open seek fill size turn stop home find step tone sqrt RSSI SSID end bit tan cos sin pow map abs max min get run put",literal:"DIGITAL_MESSAGE FIRMATA_STRING ANALOG_MESSAGE REPORT_DIGITAL REPORT_ANALOG INPUT_PULLUP SET_PIN_MODE INTERNAL2V56 SYSTEM_RESET LED_BUILTIN INTERNAL1V1 SYSEX_START INTERNAL EXTERNAL DEFAULT OUTPUT INPUT HIGH LOW"},c:[t.preprocessor,e.CLCM,e.CBCM,e.ASM,e.QSM,e.CNM]}});hljs.registerLanguage("scilab",function(e){var s=[e.CNM,{cN:"string",b:"'|\"",e:"'|\"",c:[e.BE,{b:"''"}]}];return{aliases:["sci"],l:/%?\w+/,k:{keyword:"abort break case clear catch continue do elseif else endfunction end for function global if pause return resume select try then while",literal:"%f %F %t %T %pi %eps %inf %nan %e %i %z %s",built_in:"abs and acos asin atan ceil cd chdir clearglobal cosh cos cumprod deff disp error exec execstr exists exp eye gettext floor fprintf fread fsolve imag isdef isempty isinfisnan isvector lasterror length load linspace list listfiles log10 log2 log max min msprintf mclose mopen ones or pathconvert poly printf prod pwd rand real round sinh sin size gsort sprintf sqrt strcat strcmps tring sum system tanh tan type typename warning zeros matrix"},i:'("|#|/\\*|\\s+/\\w+)',c:[{cN:"function",bK:"function",e:"$",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)"}]},{b:"[a-zA-Z_][a-zA-Z_0-9]*('+[\\.']*|[\\.']+)",e:"",r:0},{b:"\\[",e:"\\]'*[\\.']*",r:0,c:s},e.C("//","$")].concat(s)}});hljs.registerLanguage("lasso",function(e){var r="[a-zA-Z_][\\w.]*",a="<\\?(lasso(script)?|=)",t="\\]|\\?>",n={literal:"true false none minimal full all void and or not bw nbw ew new cn ncn lt lte gt gte eq neq rx nrx ft",built_in:"array date decimal duration integer map pair string tag xml null boolean bytes keyword list locale queue set stack staticarray local var variable global data self inherited currentcapture givenblock",keyword:"cache database_names database_schemanames database_tablenames define_tag define_type email_batch encode_set html_comment handle handle_error header if inline iterate ljax_target link link_currentaction link_currentgroup link_currentrecord link_detail link_firstgroup link_firstrecord link_lastgroup link_lastrecord link_nextgroup link_nextrecord link_prevgroup link_prevrecord log loop namespace_using output_none portal private protect records referer referrer repeating resultset rows search_args search_arguments select sort_args sort_arguments thread_atomic value_list while abort case else fail_if fail_ifnot fail if_empty if_false if_null if_true loop_abort loop_continue loop_count params params_up return return_value run_children soap_definetag soap_lastrequest soap_lastresponse tag_name ascending average by define descending do equals frozen group handle_failure import in into join let match max min on order parent protected provide public require returnhome skip split_thread sum take thread to trait type where with yield yieldhome"},i=e.C("",{r:0}),s={cN:"meta",b:"\\[noprocess\\]",starts:{e:"\\[/noprocess\\]",rE:!0,c:[i]}},l={cN:"meta",b:"\\[/noprocess|"+a},o={cN:"symbol",b:"'"+r+"'"},c=[e.CLCM,e.CBCM,e.inherit(e.CNM,{b:e.CNR+"|(-?infinity|NaN)\\b"}),e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null}),{cN:"string",b:"`",e:"`"},{v:[{b:"[#$]"+r},{b:"#",e:"\\d+",i:"\\W"}]},{cN:"type",b:"::\\s*",e:r,i:"\\W"},{cN:"params",v:[{b:"-(?!infinity)"+r,r:0},{b:"(\\.\\.\\.)"}]},{b:/(->|\.)\s*/,r:0,c:[o]},{cN:"class",bK:"define",rE:!0,e:"\\(|=>",c:[e.inherit(e.TM,{b:r+"(=(?!>))?|[-+*/%](?!>)"})]}];return{aliases:["ls","lassoscript"],cI:!0,l:r+"|&[lg]t;",k:n,c:[{cN:"meta",b:t,r:0,starts:{e:"\\[|"+a,rE:!0,r:0,c:[i]}},s,l,{cN:"meta",b:"\\[no_square_brackets",starts:{e:"\\[/no_square_brackets\\]",l:r+"|&[lg]t;",k:n,c:[{cN:"meta",b:t,r:0,starts:{e:"\\[noprocess\\]|"+a,rE:!0,c:[i]}},s,l].concat(c)}},{cN:"meta",b:"\\[",r:0},{cN:"meta",b:"^#!",e:"lasso9$",r:10}].concat(c)}});hljs.registerLanguage("coq",function(e){return{k:{keyword:"_ as at cofix else end exists exists2 fix for forall fun if IF in let match mod Prop return Set then Type using where with Abort About Add Admit Admitted All Arguments Assumptions Axiom Back BackTo Backtrack Bind Blacklist Canonical Cd Check Class Classes Close Coercion Coercions CoFixpoint CoInductive Collection Combined Compute Conjecture Conjectures Constant constr Constraint Constructors Context Corollary CreateHintDb Cut Declare Defined Definition Delimit Dependencies DependentDerive Drop eauto End Equality Eval Example Existential Existentials Existing Export exporting Extern Extract Extraction Fact Field Fields File Fixpoint Focus for From Function Functional Generalizable Global Goal Grab Grammar Graph Guarded Heap Hint HintDb Hints Hypotheses Hypothesis ident Identity If Immediate Implicit Import Include Inductive Infix Info Initial Inline Inspect Instance Instances Intro Intros Inversion Inversion_clear Language Left Lemma Let Libraries Library Load LoadPath Local Locate Ltac ML Mode Module Modules Monomorphic Morphism Next NoInline Notation Obligation Obligations Opaque Open Optimize Options Parameter Parameters Parametric Path Paths pattern Polymorphic Preterm Print Printing Program Projections Proof Proposition Pwd Qed Quit Rec Record Recursive Redirect Relation Remark Remove Require Reserved Reset Resolve Restart Rewrite Right Ring Rings Save Scheme Scope Scopes Script Search SearchAbout SearchHead SearchPattern SearchRewrite Section Separate Set Setoid Show Solve Sorted Step Strategies Strategy Structure SubClass Table Tables Tactic Term Test Theorem Time Timeout Transparent Type Typeclasses Types Undelimit Undo Unfocus Unfocused Unfold Universe Universes Unset Unshelve using Variable Variables Variant Verbose Visibility where with",built_in:"abstract absurd admit after apply as assert assumption at auto autorewrite autounfold before bottom btauto by case case_eq cbn cbv change classical_left classical_right clear clearbody cofix compare compute congruence constr_eq constructor contradict contradiction cut cutrewrite cycle decide decompose dependent destruct destruction dintuition discriminate discrR do double dtauto eapply eassumption eauto ecase econstructor edestruct ediscriminate eelim eexact eexists einduction einjection eleft elim elimtype enough equality erewrite eright esimplify_eq esplit evar exact exactly_once exfalso exists f_equal fail field field_simplify field_simplify_eq first firstorder fix fold fourier functional generalize generalizing gfail give_up has_evar hnf idtac in induction injection instantiate intro intro_pattern intros intuition inversion inversion_clear is_evar is_var lapply lazy left lia lra move native_compute nia nsatz omega once pattern pose progress proof psatz quote record red refine reflexivity remember rename repeat replace revert revgoals rewrite rewrite_strat right ring ring_simplify rtauto set setoid_reflexivity setoid_replace setoid_rewrite setoid_symmetry setoid_transitivity shelve shelve_unifiable simpl simple simplify_eq solve specialize split split_Rabs split_Rmult stepl stepr subst sum swap symmetry tactic tauto time timeout top transitivity trivial try tryif unfold unify until using vm_compute with"},c:[e.QSM,e.C("\\(\\*","\\*\\)"),e.CNM,{cN:"type",eB:!0,b:"\\|\\s*",e:"\\w+"},{b:/[-=]>/}]}});hljs.registerLanguage("vbscript",function(e){return{aliases:["vbs"],cI:!0,k:{keyword:"call class const dim do loop erase execute executeglobal exit for each next function if then else on error option explicit new private property let get public randomize redim rem select case set stop sub while wend with end to elseif is or xor and not class_initialize class_terminate default preserve in me byval byref step resume goto",built_in:"lcase month vartype instrrev ubound setlocale getobject rgb getref string weekdayname rnd dateadd monthname now day minute isarray cbool round formatcurrency conversions csng timevalue second year space abs clng timeserial fixs len asc isempty maths dateserial atn timer isobject filter weekday datevalue ccur isdate instr datediff formatdatetime replace isnull right sgn array snumeric log cdbl hex chr lbound msgbox ucase getlocale cos cdate cbyte rtrim join hour oct typename trim strcomp int createobject loadpicture tan formatnumber mid scriptenginebuildversion scriptengine split scriptengineminorversion cint sin datepart ltrim sqr scriptenginemajorversion time derived eval date formatpercent exp inputbox left ascw chrw regexp server response request cstr err",literal:"true false null nothing empty"},i:"//",c:[e.inherit(e.QSM,{c:[{b:'""'}]}),e.C(/'/,/$/,{r:0}),e.CNM]}});hljs.registerLanguage("vbscript-html",function(r){return{sL:"xml",c:[{b:"<%",e:"%>",sL:"vbscript"}]}});hljs.registerLanguage("less",function(e){var r="[\\w-]+",t="("+r+"|@{"+r+"})",a=[],c=[],s=function(e){return{cN:"string",b:"~?"+e+".*?"+e}},b=function(e,r,t){return{cN:e,b:r,r:t}},n={b:"\\(",e:"\\)",c:c,r:0};c.push(e.CLCM,e.CBCM,s("'"),s('"'),e.CSSNM,{b:"(url|data-uri)\\(",starts:{cN:"string",e:"[\\)\\n]",eE:!0}},b("number","#[0-9A-Fa-f]+\\b"),n,b("variable","@@?"+r,10),b("variable","@{"+r+"}"),b("built_in","~?`[^`]*?`"),{cN:"attribute",b:r+"\\s*:",e:":",rB:!0,eE:!0},{cN:"meta",b:"!important"});var i=c.concat({b:"{",e:"}",c:a}),o={bK:"when",eW:!0,c:[{bK:"and not"}].concat(c)},u={b:t+"\\s*:",rB:!0,e:"[;}]",r:0,c:[{cN:"attribute",b:t,e:":",eE:!0,starts:{eW:!0,i:"[<=$]",r:0,c:c}}]},l={cN:"keyword",b:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",starts:{e:"[;{}]",rE:!0,c:c,r:0}},C={cN:"variable",v:[{b:"@"+r+"\\s*:",r:15},{b:"@"+r}],starts:{e:"[;}]",rE:!0,c:i}},p={v:[{b:"[\\.#:&\\[>]",e:"[;{}]"},{b:t,e:"{"}],rB:!0,rE:!0,i:"[<='$\"]",r:0,c:[e.CLCM,e.CBCM,o,b("keyword","all\\b"),b("variable","@{"+r+"}"),b("selector-tag",t+"%?",0),b("selector-id","#"+t),b("selector-class","\\."+t,0),b("selector-tag","&",0),{cN:"selector-attr",b:"\\[",e:"\\]"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"\\(",e:"\\)",c:i},{b:"!important"}]};return a.push(e.CLCM,e.CBCM,l,C,u,p),{cI:!0,i:"[=>'/<($\"]",c:a}});hljs.registerLanguage("dust",function(e){var t="if eq ne lt lte gt gte select default math sep";return{aliases:["dst"],cI:!0,sL:"xml",c:[{cN:"template-tag",b:/\{[#\/]/,e:/\}/,i:/;/,c:[{cN:"name",b:/[a-zA-Z\.-]+/,starts:{eW:!0,r:0,c:[e.QSM]}}]},{cN:"template-variable",b:/\{/,e:/\}/,i:/;/,k:t}]}});hljs.registerLanguage("nginx",function(e){var r={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},b={eW:!0,l:"[a-z/_]+",k:{literal:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,r],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[r]},{cN:"regexp",c:[e.BE,r],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},r]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s+{",rB:!0,e:"{",c:[{cN:"section",b:e.UIR}],r:0},{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"attribute",b:e.UIR,starts:b}],r:0}],i:"[^\\s\\}]"}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage("dart",function(e){var t={cN:"subst",b:"\\$\\{",e:"}",k:"true false null this is new super"},r={cN:"string",v:[{b:"r'''",e:"'''"},{b:'r"""',e:'"""'},{b:"r'",e:"'",i:"\\n"},{b:'r"',e:'"',i:"\\n"},{b:"'''",e:"'''",c:[e.BE,t]},{b:'"""',e:'"""',c:[e.BE,t]},{b:"'",e:"'",i:"\\n",c:[e.BE,t]},{b:'"',e:'"',i:"\\n",c:[e.BE,t]}]};t.c=[e.CNM,r];var n={keyword:"assert async await break case catch class const continue default do else enum extends false final finally for if in is new null rethrow return super switch sync this throw true try var void while with yield abstract as dynamic export external factory get implements import library operator part set static typedef",built_in:"print Comparable DateTime Duration Function Iterable Iterator List Map Match Null Object Pattern RegExp Set Stopwatch String StringBuffer StringSink Symbol Type Uri bool double int num document window querySelector querySelectorAll Element ElementList"};return{k:n,c:[r,e.C("/\\*\\*","\\*/",{sL:"markdown"}),e.C("///","$",{sL:"markdown"}),e.CLCM,e.CBCM,{cN:"class",bK:"class interface",e:"{",eE:!0,c:[{bK:"extends implements"},e.UTM]},e.CNM,{cN:"meta",b:"@[A-Za-z]+"},{b:"=>"}]}});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",t={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:t,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:t,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b://,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("qml",function(r){var e={keyword:"in of on if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await import",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Behavior bool color coordinate date double enumeration font geocircle georectangle geoshape int list matrix4x4 parent point quaternion real rect size string url variant vector2d vector3d vector4dPromise"},t="[a-zA-Z_][a-zA-Z0-9\\._]*",a={cN:"keyword",b:"\\bproperty\\b",starts:{cN:"string",e:"(:|=|;|,|//|/\\*|$)",rE:!0}},n={cN:"keyword",b:"\\bsignal\\b",starts:{cN:"string",e:"(\\(|:|=|;|,|//|/\\*|$)",rE:!0}},o={cN:"attribute",b:"\\bid\\s*:",starts:{cN:"string",e:t,rE:!1}},i={b:t+"\\s*:",rB:!0,c:[{cN:"attribute",b:t,e:"\\s*:",eE:!0,r:0}],r:0},c={b:t+"\\s*{",e:"{",rB:!0,r:0,c:[r.inherit(r.TM,{b:t})]};return{aliases:["qt"],cI:!1,k:e,c:[{cN:"meta",b:/^\s*['"]use (strict|asm)['"]/},r.ASM,r.QSM,{cN:"string",b:"`",e:"`",c:[r.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},r.CLCM,r.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:r.CNR}],r:0},{b:"("+r.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[r.CLCM,r.CBCM,r.RM,{b:/\s*[);\]]/,r:0,sL:"xml"}],r:0},n,a,{cN:"function",bK:"function",e:/\{/,eE:!0,c:[r.inherit(r.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:[r.CLCM,r.CBCM]}],i:/\[|%/},{b:"\\."+r.IR,r:0},o,i,c],i:/#/}});hljs.registerLanguage("ruby",function(e){var b="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},c={cN:"doctag",b:"@[A-Za-z]+"},a={b:"#<",e:">"},s=[e.C("#","$",{c:[c]}),e.C("^\\=begin","^\\=end",{c:[c],r:10}),e.C("^__END__","\\n$")],n={cN:"subst",b:"#\\{",e:"}",k:r},t={cN:"string",c:[e.BE,n],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{b:/<<(-?)\w+$/,e:/^\s*\w+$/}]},i={cN:"params",b:"\\(",e:"\\)",endsParent:!0,k:r},d=[t,a,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<\\s*",c:[{b:"("+e.IR+"::)?"+e.IR}]}].concat(s)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:b}),i].concat(s)},{b:e.IR+"::"},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":(?!\\s)",c:[t,{b:b}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{cN:"params",b:/\|/,e:/\|/,k:r},{b:"("+e.RSR+"|unless)\\s*",k:"unless",c:[a,{cN:"regexp",c:[e.BE,n],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(s),r:0}].concat(s);n.c=d,i.c=d;var l="[>?]>",o="[\\w#]+\\(\\w+\\):\\d+:\\d+>",u="(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>",w=[{b:/^\s*=>/,starts:{e:"$",c:d}},{cN:"meta",b:"^("+l+"|"+o+"|"+u+")",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,i:/\/\*/,c:s.concat(w).concat(d)}});hljs.registerLanguage("erb",function(e){return{sL:"xml",c:[e.C("<%#","%>"),{b:"<%[%=-]?",e:"[%-]?%>",sL:"ruby",eB:!0,eE:!0}]}});hljs.registerLanguage("xquery",function(e){var t="for let if while then else return where group by xquery encoding versionmodule namespace boundary-space preserve strip default collation base-uri orderingcopy-namespaces order declare import schema namespace function option in allowing emptyat tumbling window sliding window start when only end when previous next stable ascendingdescending empty greatest least some every satisfies switch case typeswitch try catch andor to union intersect instance of treat as castable cast map array delete insert intoreplace value rename copy modify update",a="false true xs:string xs:integer element item xs:date xs:datetime xs:float xs:double xs:decimal QName xs:anyURI xs:long xs:int xs:short xs:byte attribute",s={b:/\$[a-zA-Z0-9\-]+/},n={cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},r={cN:"string",v:[{b:/"/,e:/"/,c:[{b:/""/,r:0}]},{b:/'/,e:/'/,c:[{b:/''/,r:0}]}]},i={cN:"meta",b:"%\\w+"},c={cN:"comment",b:"\\(:",e:":\\)",r:10,c:[{cN:"doctag",b:"@\\w+"}]},o={b:"{",e:"}"},l=[s,r,n,c,i,o];return o.c=l,{aliases:["xpath","xq"],cI:!1,l:/[a-zA-Z\$][a-zA-Z0-9_:\-]*/,i:/(proc)|(abstract)|(extends)|(until)|(#)/,k:{keyword:t,literal:a},c:l}});hljs.registerLanguage("jboss-cli",function(e){var a={b:/[\w-]+ *=/,rB:!0,r:0,c:[{cN:"attr",b:/[\w-]+/}]},r={cN:"params",b:/\(/,e:/\)/,c:[a],r:0},o={cN:"function",b:/:[\w\-.]+/,r:0},t={cN:"string",b:/\B(([\/.])[\w\-.\/=]+)+/},c={cN:"params",b:/--[\w\-=\/]+/};return{aliases:["wildfly-cli"],l:"[a-z-]+",k:{keyword:"alias batch cd clear command connect connection-factory connection-info data-source deploy deployment-info deployment-overlay echo echo-dmr help history if jdbc-driver-info jms-queue|20 jms-topic|20 ls patch pwd quit read-attribute read-operation reload rollout-plan run-batch set shutdown try unalias undeploy unset version xa-data-source",literal:"true false"},c:[e.HCM,e.QSM,c,o,t,r]}});hljs.registerLanguage("applescript",function(e){var t=e.inherit(e.QSM,{i:""}),r={cN:"params",b:"\\(",e:"\\)",c:["self",e.CNM,t]},i=e.C("--","$"),o=e.C("\\(\\*","\\*\\)",{c:["self",i]}),n=[i,o,e.HCM];return{aliases:["osascript"],k:{keyword:"about above after against and around as at back before beginning behind below beneath beside between but by considering contain contains continue copy div does eighth else end equal equals error every exit fifth first for fourth from front get given global if ignoring in into is it its last local me middle mod my ninth not of on onto or over prop property put ref reference repeat returning script second set seventh since sixth some tell tenth that the|0 then third through thru timeout times to transaction try until where while whose with without",literal:"AppleScript false linefeed return pi quote result space tab true",built_in:"alias application boolean class constant date file integer list number real record string text activate beep count delay launch log offset read round run say summarize write character characters contents day frontmost id item length month name paragraph paragraphs rest reverse running time version weekday word words year"},c:[t,e.CNM,{cN:"built_in",b:"\\b(clipboard info|the clipboard|info for|list (disks|folder)|mount volume|path to|(close|open for) access|(get|set) eof|current date|do shell script|get volume settings|random number|set volume|system attribute|system info|time to GMT|(load|run|store) script|scripting components|ASCII (character|number)|localized string|choose (application|color|file|file name|folder|from list|remote application|URL)|display (alert|dialog))\\b|^\\s*return\\b"},{cN:"literal",b:"\\b(text item delimiters|current application|missing value)\\b"},{cN:"keyword",b:"\\b(apart from|aside from|instead of|out of|greater than|isn't|(doesn't|does not) (equal|come before|come after|contain)|(greater|less) than( or equal)?|(starts?|ends|begins?) with|contained by|comes (before|after)|a (ref|reference)|POSIX file|POSIX path|(date|time) string|quoted form)\\b"},{bK:"on",i:"[${=;\\n]",c:[e.UTM,r]}].concat(n),i:"//|->|=>|\\[\\["}});hljs.registerLanguage("crmsh",function(t){var e="primitive rsc_template",r="group clone ms master location colocation order fencing_topology rsc_ticket acl_target acl_group user role tag xml",s="property rsc_defaults op_defaults",a="params meta operations op rule attributes utilization",i="read write deny defined not_defined in_range date spec in ref reference attribute type xpath version and or lt gt tag lte gte eq ne \\",o="number string",n="Master Started Slave Stopped start promote demote stop monitor true false";return{aliases:["crm","pcmk"],cI:!0,k:{keyword:a+" "+i+" "+o,literal:n},c:[t.HCM,{bK:"node",starts:{e:"\\s*([\\w_-]+:)?",starts:{cN:"title",e:"\\s*[\\$\\w_][\\w_-]*"}}},{bK:e,starts:{cN:"title",e:"\\s*[\\$\\w_][\\w_-]*",starts:{e:"\\s*@?[\\w_][\\w_\\.:-]*"}}},{b:"\\b("+r.split(" ").join("|")+")\\s+",k:r,starts:{cN:"title",e:"[\\$\\w_][\\w_-]*"}},{bK:s,starts:{cN:"title",e:"\\s*([\\w_-]+:)?"}},t.QSM,{cN:"meta",b:"(ocf|systemd|service|lsb):[\\w_:-]+",r:0},{cN:"number",b:"\\b\\d+(\\.\\d+)?(ms|s|h|m)?",r:0},{cN:"literal",b:"[-]?(infinity|inf)",r:0},{cN:"attr",b:/([A-Za-z\$_\#][\w_-]+)=/,r:0},{cN:"tag",b:"",r:0}]}});hljs.registerLanguage("taggerscript",function(e){var c={cN:"comment",b:/\$noop\(/,e:/\)/,c:[{b:/\(/,e:/\)/,c:["self",{b:/\\./}]}],r:10},r={cN:"keyword",b:/\$(?!noop)[a-zA-Z][_a-zA-Z0-9]*/,e:/\(/,eE:!0},a={cN:"variable",b:/%[_a-zA-Z0-9:]*/,e:"%"},b={cN:"symbol",b:/\\./};return{c:[c,r,a,b]}});hljs.registerLanguage("irpf90",function(e){var t={cN:"params",b:"\\(",e:"\\)"},n={literal:".False. .True.",keyword:"kind do while private call intrinsic where elsewhere type endtype endmodule endselect endinterface end enddo endif if forall endforall only contains default return stop then public subroutine|10 function program .and. .or. .not. .le. .eq. .ge. .gt. .lt. goto save else use module select case access blank direct exist file fmt form formatted iostat name named nextrec number opened rec recl sequential status unformatted unit continue format pause cycle exit c_null_char c_alert c_backspace c_form_feed flush wait decimal round iomsg synchronous nopass non_overridable pass protected volatile abstract extends import non_intrinsic value deferred generic final enumerator class associate bind enum c_int c_short c_long c_long_long c_signed_char c_size_t c_int8_t c_int16_t c_int32_t c_int64_t c_int_least8_t c_int_least16_t c_int_least32_t c_int_least64_t c_int_fast8_t c_int_fast16_t c_int_fast32_t c_int_fast64_t c_intmax_t C_intptr_t c_float c_double c_long_double c_float_complex c_double_complex c_long_double_complex c_bool c_char c_null_ptr c_null_funptr c_new_line c_carriage_return c_horizontal_tab c_vertical_tab iso_c_binding c_loc c_funloc c_associated c_f_pointer c_ptr c_funptr iso_fortran_env character_storage_size error_unit file_storage_size input_unit iostat_end iostat_eor numeric_storage_size output_unit c_f_procpointer ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode newunit contiguous recursive pad position action delim readwrite eor advance nml interface procedure namelist include sequence elemental pure integer real character complex logical dimension allocatable|10 parameter external implicit|10 none double precision assign intent optional pointer target in out common equivalence data begin_provider &begin_provider end_provider begin_shell end_shell begin_template end_template subst assert touch soft_touch provide no_dep free irp_if irp_else irp_endif irp_write irp_read",built_in:"alog alog10 amax0 amax1 amin0 amin1 amod cabs ccos cexp clog csin csqrt dabs dacos dasin datan datan2 dcos dcosh ddim dexp dint dlog dlog10 dmax1 dmin1 dmod dnint dsign dsin dsinh dsqrt dtan dtanh float iabs idim idint idnint ifix isign max0 max1 min0 min1 sngl algama cdabs cdcos cdexp cdlog cdsin cdsqrt cqabs cqcos cqexp cqlog cqsin cqsqrt dcmplx dconjg derf derfc dfloat dgamma dimag dlgama iqint qabs qacos qasin qatan qatan2 qcmplx qconjg qcos qcosh qdim qerf qerfc qexp qgamma qimag qlgama qlog qlog10 qmax1 qmin1 qmod qnint qsign qsin qsinh qsqrt qtan qtanh abs acos aimag aint anint asin atan atan2 char cmplx conjg cos cosh exp ichar index int log log10 max min nint sign sin sinh sqrt tan tanh print write dim lge lgt lle llt mod nullify allocate deallocate adjustl adjustr all allocated any associated bit_size btest ceiling count cshift date_and_time digits dot_product eoshift epsilon exponent floor fraction huge iand ibclr ibits ibset ieor ior ishft ishftc lbound len_trim matmul maxexponent maxloc maxval merge minexponent minloc minval modulo mvbits nearest pack present product radix random_number random_seed range repeat reshape rrspacing scale scan selected_int_kind selected_real_kind set_exponent shape size spacing spread sum system_clock tiny transpose trim ubound unpack verify achar iachar transfer dble entry dprod cpu_time command_argument_count get_command get_command_argument get_environment_variable is_iostat_end ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode is_iostat_eor move_alloc new_line selected_char_kind same_type_as extends_type_ofacosh asinh atanh bessel_j0 bessel_j1 bessel_jn bessel_y0 bessel_y1 bessel_yn erf erfc erfc_scaled gamma log_gamma hypot norm2 atomic_define atomic_ref execute_command_line leadz trailz storage_size merge_bits bge bgt ble blt dshiftl dshiftr findloc iall iany iparity image_index lcobound ucobound maskl maskr num_images parity popcnt poppar shifta shiftl shiftr this_image IRP_ALIGN irp_here"};return{cI:!0,k:n,i:/\/\*/,c:[e.inherit(e.ASM,{cN:"string",r:0}),e.inherit(e.QSM,{cN:"string",r:0}),{cN:"function",bK:"subroutine function program",i:"[${=\\n]",c:[e.UTM,t]},e.C("!","$",{r:0}),e.C("begin_doc","end_doc",{r:10}),{cN:"number",b:"(?=\\b|\\+|\\-|\\.)(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*)(?:[de][+-]?\\d+)?\\b\\.?",r:0}]}});hljs.registerLanguage("golo",function(e){return{k:{keyword:"println readln print import module function local return let var while for foreach times in case when match with break continue augment augmentation each find filter reduce if then else otherwise try catch finally raise throw orIfNull DynamicObject|10 DynamicVariable struct Observable map set vector list array",literal:"true false null"},c:[e.HCM,e.QSM,e.CNM,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("pony",function(e){var r={keyword:"actor addressof and as be break class compile_error compile_intrinsicconsume continue delegate digestof do else elseif embed end errorfor fun if ifdef in interface is isnt lambda let match new not objector primitive recover repeat return struct then trait try type until use var where while with xor",meta:"iso val tag trn box ref",literal:"this false true"},t={cN:"string",b:'"""',e:'"""',r:10},c={cN:"string",b:'"',e:'"',c:[e.BE]},i={cN:"string",b:"'",e:"'",c:[e.BE],r:0},n={cN:"type",b:"\\b_?[A-Z][\\w]*",r:0},s={b:e.IR+"'",r:0},a={cN:"class",bK:"class actor",e:"$",c:[e.TM,e.CLCM]},o={cN:"function",bK:"new fun",e:"=>",c:[e.TM,{b:/\(/,e:/\)/,c:[n,s,e.CNM,e.CBCM]},{b:/:/,eW:!0,c:[n]},e.CLCM]};return{k:r,c:[a,o,n,t,c,i,s,e.CNM,e.CLCM,e.CBCM]}});hljs.registerLanguage("fsharp",function(e){var t={b:"<",e:">",c:[e.inherit(e.TM,{b:/'[a-zA-Z0-9_]+/})]};return{aliases:["fs"],k:"abstract and as assert base begin class default delegate do done downcast downto elif else end exception extern false finally for fun function global if in inherit inline interface internal lazy let match member module mutable namespace new null of open or override private public rec return sig static struct then to true try type upcast use val void when while with yield",i:/\/\*/,c:[{cN:"keyword",b:/\b(yield|return|let|do)!/},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},{cN:"string",b:'"""',e:'"""'},e.C("\\(\\*","\\*\\)"),{cN:"class",bK:"type",e:"\\(|=|$",eE:!0,c:[e.UTM,t]},{cN:"meta",b:"\\[<",e:">\\]",r:10},{cN:"symbol",b:"\\B('[A-Za-z])\\b",c:[e.BE]},e.CLCM,e.inherit(e.QSM,{i:null}),e.CNM]}});hljs.registerLanguage("scheme",function(e){var t="[^\\(\\)\\[\\]\\{\\}\",'`;#|\\\\\\s]+",r="(\\-|\\+)?\\d+([./]\\d+)?",a=r+"[+\\-]"+r+"i",i={"builtin-name":"case-lambda call/cc class define-class exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules ' * + , ,@ - ... / ; < <= = => > >= ` abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string=? string>? string? substring symbol->string symbol? tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?"},n={cN:"meta",b:"^#!",e:"$"},c={cN:"literal",b:"(#t|#f|#\\\\"+t+"|#\\\\.)"},l={cN:"number",v:[{b:r,r:0},{b:a,r:0},{b:"#b[0-1]+(/[0-1]+)?"},{b:"#o[0-7]+(/[0-7]+)?"},{b:"#x[0-9a-f]+(/[0-9a-f]+)?"}]},s=e.QSM,o=[e.C(";","$",{r:0}),e.C("#\\|","\\|#")],u={b:t,r:0},p={cN:"symbol",b:"'"+t},d={eW:!0,r:0},m={v:[{b:/'/},{b:"`"}],c:[{b:"\\(",e:"\\)",c:["self",c,s,l,u,p]}]},g={cN:"name",b:t,l:t,k:i},h={b:/lambda/,eW:!0,rB:!0,c:[g,{b:/\(/,e:/\)/,endsParent:!0,c:[u]}]},b={v:[{b:"\\(",e:"\\)"},{b:"\\[",e:"\\]"}],c:[h,g,d]};return d.c=[c,l,s,u,p,m,b].concat(o),{i:/\S/,c:[n,l,s,p,m,b].concat(o)}});hljs.registerLanguage("twig",function(e){var t={cN:"params",b:"\\(",e:"\\)"},a="attribute block constant cycle date dump include max min parent random range source template_from_string",r={bK:a,k:{name:a},r:0,c:[t]},c={b:/\|[A-Za-z_]+:?/,k:"abs batch capitalize convert_encoding date date_modify default escape first format join json_encode keys last length lower merge nl2br number_format raw replace reverse round slice sort split striptags title trim upper url_encode",c:[r]},s="autoescape block do embed extends filter flush for if import include macro sandbox set spaceless use verbatim";return s=s+" "+s.split(" ").map(function(e){return"end"+e}).join(" "),{aliases:["craftcms"],cI:!0,sL:"xml",c:[e.C(/\{#/,/#}/),{cN:"template-tag",b:/\{%/,e:/%}/,c:[{cN:"name",b:/\w+/,k:s,starts:{eW:!0,c:[c,r],r:0}}]},{cN:"template-variable",b:/\{\{/,e:/}}/,c:["self",c,r]}]}});hljs.registerLanguage("matlab",function(e){var a=[e.CNM,{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]}],s={r:0,c:[{b:/'['\.]*/}]};return{k:{keyword:"break case catch classdef continue else elseif end enumerated events for function global if methods otherwise parfor persistent properties return spmd switch try while",built_in:"sin sind sinh asin asind asinh cos cosd cosh acos acosd acosh tan tand tanh atan atand atan2 atanh sec secd sech asec asecd asech csc cscd csch acsc acscd acsch cot cotd coth acot acotd acoth hypot exp expm1 log log1p log10 log2 pow2 realpow reallog realsqrt sqrt nthroot nextpow2 abs angle complex conj imag real unwrap isreal cplxpair fix floor ceil round mod rem sign airy besselj bessely besselh besseli besselk beta betainc betaln ellipj ellipke erf erfc erfcx erfinv expint gamma gammainc gammaln psi legendre cross dot factor isprime primes gcd lcm rat rats perms nchoosek factorial cart2sph cart2pol pol2cart sph2cart hsv2rgb rgb2hsv zeros ones eye repmat rand randn linspace logspace freqspace meshgrid accumarray size length ndims numel disp isempty isequal isequalwithequalnans cat reshape diag blkdiag tril triu fliplr flipud flipdim rot90 find sub2ind ind2sub bsxfun ndgrid permute ipermute shiftdim circshift squeeze isscalar isvector ans eps realmax realmin pi i inf nan isnan isinf isfinite j why compan gallery hadamard hankel hilb invhilb magic pascal rosser toeplitz vander wilkinson"},i:'(//|"|#|/\\*|\\s+/\\w+)',c:[{cN:"function",bK:"function",e:"$",c:[e.UTM,{cN:"params",v:[{b:"\\(",e:"\\)"},{b:"\\[",e:"\\]"}]}]},{b:/[a-zA-Z_][a-zA-Z_0-9]*'['\.]*/,rB:!0,r:0,c:[{b:/[a-zA-Z_][a-zA-Z_0-9]*/,r:0},s.c[0]]},{b:"\\[",e:"\\]",c:a,r:0,starts:s},{b:"\\{",e:/}/,c:a,r:0,starts:s},{b:/\)/,r:0,starts:s},e.C("^\\s*\\%\\{\\s*$","^\\s*\\%\\}\\s*$"),e.C("\\%","$")].concat(a)}});hljs.registerLanguage("processing",function(e){return{k:{keyword:"BufferedReader PVector PFont PImage PGraphics HashMap boolean byte char color double float int long String Array FloatDict FloatList IntDict IntList JSONArray JSONObject Object StringDict StringList Table TableRow XML false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private",literal:"P2D P3D HALF_PI PI QUARTER_PI TAU TWO_PI",title:"setup draw",built_in:"displayHeight displayWidth mouseY mouseX mousePressed pmouseX pmouseY key keyCode pixels focused frameCount frameRate height width size createGraphics beginDraw createShape loadShape PShape arc ellipse line point quad rect triangle bezier bezierDetail bezierPoint bezierTangent curve curveDetail curvePoint curveTangent curveTightness shape shapeMode beginContour beginShape bezierVertex curveVertex endContour endShape quadraticVertex vertex ellipseMode noSmooth rectMode smooth strokeCap strokeJoin strokeWeight mouseClicked mouseDragged mouseMoved mousePressed mouseReleased mouseWheel keyPressed keyPressedkeyReleased keyTyped print println save saveFrame day hour millis minute month second year background clear colorMode fill noFill noStroke stroke alpha blue brightness color green hue lerpColor red saturation modelX modelY modelZ screenX screenY screenZ ambient emissive shininess specular add createImage beginCamera camera endCamera frustum ortho perspective printCamera printProjection cursor frameRate noCursor exit loop noLoop popStyle pushStyle redraw binary boolean byte char float hex int str unbinary unhex join match matchAll nf nfc nfp nfs split splitTokens trim append arrayCopy concat expand reverse shorten sort splice subset box sphere sphereDetail createInput createReader loadBytes loadJSONArray loadJSONObject loadStrings loadTable loadXML open parseXML saveTable selectFolder selectInput beginRaw beginRecord createOutput createWriter endRaw endRecord PrintWritersaveBytes saveJSONArray saveJSONObject saveStream saveStrings saveXML selectOutput popMatrix printMatrix pushMatrix resetMatrix rotate rotateX rotateY rotateZ scale shearX shearY translate ambientLight directionalLight lightFalloff lights lightSpecular noLights normal pointLight spotLight image imageMode loadImage noTint requestImage tint texture textureMode textureWrap blend copy filter get loadPixels set updatePixels blendMode loadShader PShaderresetShader shader createFont loadFont text textFont textAlign textLeading textMode textSize textWidth textAscent textDescent abs ceil constrain dist exp floor lerp log mag map max min norm pow round sq sqrt acos asin atan atan2 cos degrees radians sin tan noise noiseDetail noiseSeed random randomGaussian randomSeed"},c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.CNM]}});hljs.registerLanguage("llvm",function(e){var n="([-a-zA-Z$._][\\w\\-$.]*)";return{k:"begin end true false declare define global constant private linker_private internal available_externally linkonce linkonce_odr weak weak_odr appending dllimport dllexport common default hidden protected extern_weak external thread_local zeroinitializer undef null to tail target triple datalayout volatile nuw nsw nnan ninf nsz arcp fast exact inbounds align addrspace section alias module asm sideeffect gc dbg linker_private_weak attributes blockaddress initialexec localdynamic localexec prefix unnamed_addr ccc fastcc coldcc x86_stdcallcc x86_fastcallcc arm_apcscc arm_aapcscc arm_aapcs_vfpcc ptx_device ptx_kernel intel_ocl_bicc msp430_intrcc spir_func spir_kernel x86_64_sysvcc x86_64_win64cc x86_thiscallcc cc c signext zeroext inreg sret nounwind noreturn noalias nocapture byval nest readnone readonly inlinehint noinline alwaysinline optsize ssp sspreq noredzone noimplicitfloat naked builtin cold nobuiltin noduplicate nonlazybind optnone returns_twice sanitize_address sanitize_memory sanitize_thread sspstrong uwtable returned type opaque eq ne slt sgt sle sge ult ugt ule uge oeq one olt ogt ole oge ord uno ueq une x acq_rel acquire alignstack atomic catch cleanup filter inteldialect max min monotonic nand personality release seq_cst singlethread umax umin unordered xchg add fadd sub fsub mul fmul udiv sdiv fdiv urem srem frem shl lshr ashr and or xor icmp fcmp phi call trunc zext sext fptrunc fpext uitofp sitofp fptoui fptosi inttoptr ptrtoint bitcast addrspacecast select va_arg ret br switch invoke unwind unreachable indirectbr landingpad resume malloc alloca free load store getelementptr extractelement insertelement shufflevector getresult extractvalue insertvalue atomicrmw cmpxchg fence argmemonly double",c:[{cN:"keyword",b:"i\\d+"},e.C(";","\\n",{r:0}),e.QSM,{cN:"string",v:[{b:'"',e:'[^\\\\]"'}],r:0},{cN:"title",v:[{b:"@"+n},{b:"@\\d+"},{b:"!"+n},{b:"!\\d+"+n}]},{cN:"symbol",v:[{b:"%"+n},{b:"%\\d+"},{b:"#\\d+"}]},{cN:"number",v:[{b:"0[xX][a-fA-F0-9]+"},{b:"-?\\d+(?:[.]\\d+)?(?:[eE][-+]?\\d+(?:[.]\\d+)?)?"}],r:0}]}});hljs.registerLanguage("capnproto",function(t){return{aliases:["capnp"],k:{keyword:"struct enum interface union group import using const annotation extends in of on as with from fixed",built_in:"Void Bool Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64 Float32 Float64 Text Data AnyPointer AnyStruct Capability List",literal:"true false"},c:[t.QSM,t.NM,t.HCM,{cN:"meta",b:/@0x[\w\d]{16};/,i:/\n/},{cN:"symbol",b:/@\d+\b/},{cN:"class",bK:"struct enum",e:/\{/,i:/\n/,c:[t.inherit(t.TM,{starts:{eW:!0,eE:!0}})]},{cN:"class",bK:"interface",e:/\{/,i:/\n/,c:[t.inherit(t.TM,{starts:{eW:!0,eE:!0}})]}]}});hljs.registerLanguage("dns",function(d){return{aliases:["bind","zone"],k:{keyword:"IN A AAAA AFSDB APL CAA CDNSKEY CDS CERT CNAME DHCID DLV DNAME DNSKEY DS HIP IPSECKEY KEY KX LOC MX NAPTR NS NSEC NSEC3 NSEC3PARAM PTR RRSIG RP SIG SOA SRV SSHFP TA TKEY TLSA TSIG TXT"},c:[d.C(";","$",{r:0}),{cN:"meta",b:/^\$(TTL|GENERATE|INCLUDE|ORIGIN)\b/},{cN:"number",b:"((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))\\b"},{cN:"number",b:"((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\b"},d.inherit(d.NM,{b:/\b\d+[dhwm]?/})]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("vala",function(t){return{k:{keyword:"char uchar unichar int uint long ulong short ushort int8 int16 int32 int64 uint8 uint16 uint32 uint64 float double bool struct enum string void weak unowned owned async signal static abstract interface override virtual delegate if while do for foreach else switch case break default return try catch public private protected internal using new this get set const stdout stdin stderr var",built_in:"DBus GLib CCode Gee Object Gtk Posix",literal:"false true null"},c:[{cN:"class",bK:"class interface namespace",e:"{",eE:!0,i:"[^,:\\n\\s\\.]",c:[t.UTM]},t.CLCM,t.CBCM,{cN:"string",b:'"""',e:'"""',r:5},t.ASM,t.QSM,t.CNM,{cN:"meta",b:"^#",e:"$",r:2}]}});hljs.registerLanguage("sql",function(e){var t=e.C("--","$");return{cI:!0,i:/[<>{}*#]/,c:[{bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment",e:/;/,eW:!0,l:/[\w\.]+/,k:{keyword:"abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null",built_in:"array bigint binary bit blob boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text varchar varying void"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t]},e.CBCM,t]}});hljs.registerLanguage("r",function(e){var r="([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*";return{c:[e.HCM,{b:r,l:r,k:{keyword:"function if in break next repeat else for return switch while try tryCatch stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",r:0},{cN:"number",b:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",r:0},{cN:"number",b:"\\d+\\.(?!\\d)(?:i\\b)?",r:0},{cN:"number",b:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{b:"`",e:"`",r:0},{cN:"string",c:[e.BE],v:[{b:'"',e:'"'},{b:"'",e:"'"}]}]}});hljs.registerLanguage("nimrod",function(t){return{aliases:["nim"],k:{keyword:"addr and as asm bind block break case cast const continue converter discard distinct div do elif else end enum except export finally for from generic if import in include interface is isnot iterator let macro method mixin mod nil not notin object of or out proc ptr raise ref return shl shr static template try tuple type using var when while with without xor yield",literal:"shared guarded stdin stdout stderr result true false",built_in:"int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float float32 float64 bool char string cstring pointer expr stmt void auto any range array openarray varargs seq set clong culong cchar cschar cshort cint csize clonglong cfloat cdouble clongdouble cuchar cushort cuint culonglong cstringarray semistatic"},c:[{cN:"meta",b:/{\./,e:/\.}/,r:10},{cN:"string",b:/[a-zA-Z]\w*"/,e:/"/,c:[{b:/""/}]},{cN:"string",b:/([a-zA-Z]\w*)?"""/,e:/"""/},t.QSM,{cN:"type",b:/\b[A-Z]\w+\b/,r:0},{cN:"number",r:0,v:[{b:/\b(0[xX][0-9a-fA-F][_0-9a-fA-F]*)('?[iIuU](8|16|32|64))?/},{b:/\b(0o[0-7][_0-7]*)('?[iIuUfF](8|16|32|64))?/},{b:/\b(0(b|B)[01][_01]*)('?[iIuUfF](8|16|32|64))?/},{b:/\b(\d[_\d]*)('?[iIuUfF](8|16|32|64))?/}]},t.HCM]}});hljs.registerLanguage("step21",function(e){var i="[A-Z_][A-Z0-9_.]*",r={keyword:"HEADER ENDSEC DATA"},t={cN:"meta",b:"ISO-10303-21;",r:10},n={cN:"meta",b:"END-ISO-10303-21;",r:10};return{aliases:["p21","step","stp"],cI:!0,l:i,k:r,c:[t,n,e.CLCM,e.CBCM,e.C("/\\*\\*!","\\*/"),e.CNM,e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null}),{cN:"string",b:"'",e:"'"},{cN:"symbol",v:[{b:"#",e:"\\d+",i:"\\W"}]}]}});hljs.registerLanguage("axapta",function(e){return{k:"false int abstract private char boolean static null if for true while long throw finally protected final return void enum else break new catch byte super case short default double public try this switch continue reverse firstfast firstonly forupdate nofetch sum avg minof maxof count order group by asc desc index hint like dispaly edit client server ttsbegin ttscommit str real date container anytype common div mod",c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.CNM,{cN:"meta",b:"#",e:"$"},{cN:"class",bK:"class interface",e:"{",eE:!0,i:":",c:[{bK:"extends implements"},e.UTM]}]}});hljs.registerLanguage("ruleslanguage",function(T){return{k:{keyword:"BILL_PERIOD BILL_START BILL_STOP RS_EFFECTIVE_START RS_EFFECTIVE_STOP RS_JURIS_CODE RS_OPCO_CODE INTDADDATTRIBUTE|5 INTDADDVMSG|5 INTDBLOCKOP|5 INTDBLOCKOPNA|5 INTDCLOSE|5 INTDCOUNT|5 INTDCOUNTSTATUSCODE|5 INTDCREATEMASK|5 INTDCREATEDAYMASK|5 INTDCREATEFACTORMASK|5 INTDCREATEHANDLE|5 INTDCREATEOVERRIDEDAYMASK|5 INTDCREATEOVERRIDEMASK|5 INTDCREATESTATUSCODEMASK|5 INTDCREATETOUPERIOD|5 INTDDELETE|5 INTDDIPTEST|5 INTDEXPORT|5 INTDGETERRORCODE|5 INTDGETERRORMESSAGE|5 INTDISEQUAL|5 INTDJOIN|5 INTDLOAD|5 INTDLOADACTUALCUT|5 INTDLOADDATES|5 INTDLOADHIST|5 INTDLOADLIST|5 INTDLOADLISTDATES|5 INTDLOADLISTENERGY|5 INTDLOADLISTHIST|5 INTDLOADRELATEDCHANNEL|5 INTDLOADSP|5 INTDLOADSTAGING|5 INTDLOADUOM|5 INTDLOADUOMDATES|5 INTDLOADUOMHIST|5 INTDLOADVERSION|5 INTDOPEN|5 INTDREADFIRST|5 INTDREADNEXT|5 INTDRECCOUNT|5 INTDRELEASE|5 INTDREPLACE|5 INTDROLLAVG|5 INTDROLLPEAK|5 INTDSCALAROP|5 INTDSCALE|5 INTDSETATTRIBUTE|5 INTDSETDSTPARTICIPANT|5 INTDSETSTRING|5 INTDSETVALUE|5 INTDSETVALUESTATUS|5 INTDSHIFTSTARTTIME|5 INTDSMOOTH|5 INTDSORT|5 INTDSPIKETEST|5 INTDSUBSET|5 INTDTOU|5 INTDTOURELEASE|5 INTDTOUVALUE|5 INTDUPDATESTATS|5 INTDVALUE|5 STDEV INTDDELETEEX|5 INTDLOADEXACTUAL|5 INTDLOADEXCUT|5 INTDLOADEXDATES|5 INTDLOADEX|5 INTDLOADEXRELATEDCHANNEL|5 INTDSAVEEX|5 MVLOAD|5 MVLOADACCT|5 MVLOADACCTDATES|5 MVLOADACCTHIST|5 MVLOADDATES|5 MVLOADHIST|5 MVLOADLIST|5 MVLOADLISTDATES|5 MVLOADLISTHIST|5 IF FOR NEXT DONE SELECT END CALL ABORT CLEAR CHANNEL FACTOR LIST NUMBER OVERRIDE SET WEEK DISTRIBUTIONNODE ELSE WHEN THEN OTHERWISE IENUM CSV INCLUDE LEAVE RIDER SAVE DELETE NOVALUE SECTION WARN SAVE_UPDATE DETERMINANT LABEL REPORT REVENUE EACH IN FROM TOTAL CHARGE BLOCK AND OR CSV_FILE RATE_CODE AUXILIARY_DEMAND UIDACCOUNT RS BILL_PERIOD_SELECT HOURS_PER_MONTH INTD_ERROR_STOP SEASON_SCHEDULE_NAME ACCOUNTFACTOR ARRAYUPPERBOUND CALLSTOREDPROC GETADOCONNECTION GETCONNECT GETDATASOURCE GETQUALIFIER GETUSERID HASVALUE LISTCOUNT LISTOP LISTUPDATE LISTVALUE PRORATEFACTOR RSPRORATE SETBINPATH SETDBMONITOR WQ_OPEN BILLINGHOURS DATE DATEFROMFLOAT DATETIMEFROMSTRING DATETIMETOSTRING DATETOFLOAT DAY DAYDIFF DAYNAME DBDATETIME HOUR MINUTE MONTH MONTHDIFF MONTHHOURS MONTHNAME ROUNDDATE SAMEWEEKDAYLASTYEAR SECOND WEEKDAY WEEKDIFF YEAR YEARDAY YEARSTR COMPSUM HISTCOUNT HISTMAX HISTMIN HISTMINNZ HISTVALUE MAXNRANGE MAXRANGE MINRANGE COMPIKVA COMPKVA COMPKVARFROMKQKW COMPLF IDATTR FLAG LF2KW LF2KWH MAXKW POWERFACTOR READING2USAGE AVGSEASON MAXSEASON MONTHLYMERGE SEASONVALUE SUMSEASON ACCTREADDATES ACCTTABLELOAD CONFIGADD CONFIGGET CREATEOBJECT CREATEREPORT EMAILCLIENT EXPBLKMDMUSAGE EXPMDMUSAGE EXPORT_USAGE FACTORINEFFECT GETUSERSPECIFIEDSTOP INEFFECT ISHOLIDAY RUNRATE SAVE_PROFILE SETREPORTTITLE USEREXIT WATFORRUNRATE TO TABLE ACOS ASIN ATAN ATAN2 BITAND CEIL COS COSECANT COSH COTANGENT DIVQUOT DIVREM EXP FABS FLOOR FMOD FREPM FREXPN LOG LOG10 MAX MAXN MIN MINNZ MODF POW ROUND ROUND2VALUE ROUNDINT SECANT SIN SINH SQROOT TAN TANH FLOAT2STRING FLOAT2STRINGNC INSTR LEFT LEN LTRIM MID RIGHT RTRIM STRING STRINGNC TOLOWER TOUPPER TRIM NUMDAYS READ_DATE STAGING",built_in:"IDENTIFIER OPTIONS XML_ELEMENT XML_OP XML_ELEMENT_OF DOMDOCCREATE DOMDOCLOADFILE DOMDOCLOADXML DOMDOCSAVEFILE DOMDOCGETROOT DOMDOCADDPI DOMNODEGETNAME DOMNODEGETTYPE DOMNODEGETVALUE DOMNODEGETCHILDCT DOMNODEGETFIRSTCHILD DOMNODEGETSIBLING DOMNODECREATECHILDELEMENT DOMNODESETATTRIBUTE DOMNODEGETCHILDELEMENTCT DOMNODEGETFIRSTCHILDELEMENT DOMNODEGETSIBLINGELEMENT DOMNODEGETATTRIBUTECT DOMNODEGETATTRIBUTEI DOMNODEGETATTRIBUTEBYNAME DOMNODEGETBYNAME"},c:[T.CLCM,T.CBCM,T.ASM,T.QSM,T.CNM,{cN:"literal",v:[{b:"#\\s+[a-zA-Z\\ \\.]*",r:0},{b:"#[a-zA-Z\\ \\.]+"}]}]}});hljs.registerLanguage("roboconf",function(a){var e="[a-zA-Z-_][^\\n{]+\\{",n={cN:"attribute",b:/[a-zA-Z-_]+/,e:/\s*:/,eE:!0,starts:{e:";",r:0,c:[{cN:"variable",b:/\.[a-zA-Z-_]+/},{cN:"keyword",b:/\(optional\)/}]}};return{aliases:["graph","instances"],cI:!0,k:"import",c:[{b:"^facet "+e,e:"}",k:"facet",c:[n,a.HCM]},{b:"^\\s*instance of "+e,e:"}",k:"name count channels instance-data instance-state instance of",i:/\S/,c:["self",n,a.HCM]},{b:"^"+e,e:"}",c:[n,a.HCM]},a.HCM]}});hljs.registerLanguage("gradle",function(e){return{cI:!0,k:{keyword:"task project allprojects subprojects artifacts buildscript configurations dependencies repositories sourceSets description delete from into include exclude source classpath destinationDir includes options sourceCompatibility targetCompatibility group flatDir doLast doFirst flatten todir fromdir ant def abstract break case catch continue default do else extends final finally for if implements instanceof native new private protected public return static switch synchronized throw throws transient try volatile while strictfp package import false null super this true antlrtask checkstyle codenarc copy boolean byte char class double float int interface long short void compile runTime file fileTree abs any append asList asWritable call collect compareTo count div dump each eachByte eachFile eachLine every find findAll flatten getAt getErr getIn getOut getText grep immutable inject inspect intersect invokeMethods isCase join leftShift minus multiply newInputStream newOutputStream newPrintWriter newReader newWriter next plus pop power previous print println push putAt read readBytes readLines reverse reverseEach round size sort splitEachLine step subMap times toInteger toList tokenize upto waitForOrKill withPrintWriter withReader withStream withWriter withWriterAppend write writeLine"},c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.NM,e.RM]}});hljs.registerLanguage("ceylon",function(e){var a="assembly module package import alias class interface object given value assign void function new of extends satisfies abstracts in out return break continue throw assert dynamic if else switch case for while try catch finally then let this outer super is exists nonempty",t="shared abstract formal default actual variable late native deprecatedfinal sealed annotation suppressWarnings small",s="doc by license see throws tagged",n={cN:"subst",eB:!0,eE:!0,b:/``/,e:/``/,k:a,r:10},r=[{cN:"string",b:'"""',e:'"""',r:10},{cN:"string",b:'"',e:'"',c:[n]},{cN:"string",b:"'",e:"'"},{cN:"number",b:"#[0-9a-fA-F_]+|\\$[01_]+|[0-9_]+(?:\\.[0-9_](?:[eE][+-]?\\d+)?)?[kMGTPmunpf]?",r:0}];return n.c=r,{k:{keyword:a+" "+t,meta:s},i:"\\$[^01]|#[^0-9a-fA-F]",c:[e.CLCM,e.C("/\\*","\\*/",{c:["self"]}),{cN:"meta",b:'@[a-z]\\w*(?:\\:"[^"]*")?'}].concat(r)}});hljs.registerLanguage("puppet",function(e){var s={keyword:"and case default else elsif false if in import enherits node or true undef unless main settings $string ",literal:"alias audit before loglevel noop require subscribe tag owner ensure group mode name|0 changes context force incl lens load_path onlyif provider returns root show_diff type_check en_address ip_address realname command environment hour monute month monthday special target weekday creates cwd ogoutput refresh refreshonly tries try_sleep umask backup checksum content ctime force ignore links mtime purge recurse recurselimit replace selinux_ignore_defaults selrange selrole seltype seluser source souirce_permissions sourceselect validate_cmd validate_replacement allowdupe attribute_membership auth_membership forcelocal gid ia_load_module members system host_aliases ip allowed_trunk_vlans description device_url duplex encapsulation etherchannel native_vlan speed principals allow_root auth_class auth_type authenticate_user k_of_n mechanisms rule session_owner shared options device fstype enable hasrestart directory present absent link atboot blockdevice device dump pass remounts poller_tag use message withpath adminfile allow_virtual allowcdrom category configfiles flavor install_options instance package_settings platform responsefile status uninstall_options vendor unless_system_user unless_uid binary control flags hasstatus manifest pattern restart running start stop allowdupe auths expiry gid groups home iterations key_membership keys managehome membership password password_max_age password_min_age profile_membership profiles project purge_ssh_keys role_membership roles salt shell uid baseurl cost descr enabled enablegroups exclude failovermethod gpgcheck gpgkey http_caching include includepkgs keepalive metadata_expire metalink mirrorlist priority protect proxy proxy_password proxy_username repo_gpgcheck s3_enabled skip_if_unavailable sslcacert sslclientcert sslclientkey sslverify mounted",built_in:"architecture augeasversion blockdevices boardmanufacturer boardproductname boardserialnumber cfkey dhcp_servers domain ec2_ ec2_userdata facterversion filesystems ldom fqdn gid hardwareisa hardwaremodel hostname id|0 interfaces ipaddress ipaddress_ ipaddress6 ipaddress6_ iphostnumber is_virtual kernel kernelmajversion kernelrelease kernelversion kernelrelease kernelversion lsbdistcodename lsbdistdescription lsbdistid lsbdistrelease lsbmajdistrelease lsbminordistrelease lsbrelease macaddress macaddress_ macosx_buildversion macosx_productname macosx_productversion macosx_productverson_major macosx_productversion_minor manufacturer memoryfree memorysize netmask metmask_ network_ operatingsystem operatingsystemmajrelease operatingsystemrelease osfamily partitions path physicalprocessorcount processor processorcount productname ps puppetversion rubysitedir rubyversion selinux selinux_config_mode selinux_config_policy selinux_current_mode selinux_current_mode selinux_enforced selinux_policyversion serialnumber sp_ sshdsakey sshecdsakey sshrsakey swapencrypted swapfree swapsize timezone type uniqueid uptime uptime_days uptime_hours uptime_seconds uuid virtual vlans xendomains zfs_version zonenae zones zpool_version"},r=e.C("#","$"),a="([A-Za-z_]|::)(\\w|::)*",i=e.inherit(e.TM,{b:a}),o={cN:"variable",b:"\\$"+a},t={cN:"string",c:[e.BE,o],v:[{b:/'/,e:/'/},{b:/"/,e:/"/}]};return{aliases:["pp"],c:[r,o,t,{bK:"class",e:"\\{|;",i:/=/,c:[i,r]},{bK:"define",e:/\{/,c:[{cN:"section",b:e.IR,endsParent:!0}]},{b:e.IR+"\\s+\\{",rB:!0,e:/\S/,c:[{cN:"keyword",b:e.IR},{b:/\{/,e:/\}/,k:s,r:0,c:[t,r,{b:"[a-zA-Z_]+\\s*=>",rB:!0,e:"=>",c:[{cN:"attr",b:e.IR}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},o]}],r:0}]}});hljs.registerLanguage("stata",function(e){return{aliases:["do","ado"],cI:!0,k:"if else in foreach for forv forva forval forvalu forvalue forvalues by bys bysort xi quietly qui capture about ac ac_7 acprplot acprplot_7 adjust ado adopath adoupdate alpha ameans an ano anov anova anova_estat anova_terms anovadef aorder ap app appe appen append arch arch_dr arch_estat arch_p archlm areg areg_p args arima arima_dr arima_estat arima_p as asmprobit asmprobit_estat asmprobit_lf asmprobit_mfx__dlg asmprobit_p ass asse asser assert avplot avplot_7 avplots avplots_7 bcskew0 bgodfrey binreg bip0_lf biplot bipp_lf bipr_lf bipr_p biprobit bitest bitesti bitowt blogit bmemsize boot bootsamp bootstrap bootstrap_8 boxco_l boxco_p boxcox boxcox_6 boxcox_p bprobit br break brier bro brow brows browse brr brrstat bs bs_7 bsampl_w bsample bsample_7 bsqreg bstat bstat_7 bstat_8 bstrap bstrap_7 ca ca_estat ca_p cabiplot camat canon canon_8 canon_8_p canon_estat canon_p cap caprojection capt captu captur capture cat cc cchart cchart_7 cci cd censobs_table centile cf char chdir checkdlgfiles checkestimationsample checkhlpfiles checksum chelp ci cii cl class classutil clear cli clis clist clo clog clog_lf clog_p clogi clogi_sw clogit clogit_lf clogit_p clogitp clogl_sw cloglog clonevar clslistarray cluster cluster_measures cluster_stop cluster_tree cluster_tree_8 clustermat cmdlog cnr cnre cnreg cnreg_p cnreg_sw cnsreg codebook collaps4 collapse colormult_nb colormult_nw compare compress conf confi confir confirm conren cons const constr constra constrai constrain constraint continue contract copy copyright copysource cor corc corr corr2data corr_anti corr_kmo corr_smc corre correl correla correlat correlate corrgram cou coun count cox cox_p cox_sw coxbase coxhaz coxvar cprplot cprplot_7 crc cret cretu cretur creturn cross cs cscript cscript_log csi ct ct_is ctset ctst_5 ctst_st cttost cumsp cumsp_7 cumul cusum cusum_7 cutil d|0 datasig datasign datasigna datasignat datasignatu datasignatur datasignature datetof db dbeta de dec deco decod decode deff des desc descr descri describ describe destring dfbeta dfgls dfuller di di_g dir dirstats dis discard disp disp_res disp_s displ displa display distinct do doe doed doedi doedit dotplot dotplot_7 dprobit drawnorm drop ds ds_util dstdize duplicates durbina dwstat dydx e|0 ed edi edit egen eivreg emdef en enc enco encod encode eq erase ereg ereg_lf ereg_p ereg_sw ereghet ereghet_glf ereghet_glf_sh ereghet_gp ereghet_ilf ereghet_ilf_sh ereghet_ip eret eretu eretur ereturn err erro error est est_cfexist est_cfname est_clickable est_expand est_hold est_table est_unhold est_unholdok estat estat_default estat_summ estat_vce_only esti estimates etodow etof etomdy ex exi exit expand expandcl fac fact facto factor factor_estat factor_p factor_pca_rotated factor_rotate factormat fcast fcast_compute fcast_graph fdades fdadesc fdadescr fdadescri fdadescrib fdadescribe fdasav fdasave fdause fh_st file open file read file close file filefilter fillin find_hlp_file findfile findit findit_7 fit fl fli flis flist for5_0 form forma format fpredict frac_154 frac_adj frac_chk frac_cox frac_ddp frac_dis frac_dv frac_in frac_mun frac_pp frac_pq frac_pv frac_wgt frac_xo fracgen fracplot fracplot_7 fracpoly fracpred fron_ex fron_hn fron_p fron_tn fron_tn2 frontier ftodate ftoe ftomdy ftowdate g|0 gamhet_glf gamhet_gp gamhet_ilf gamhet_ip gamma gamma_d2 gamma_p gamma_sw gammahet gdi_hexagon gdi_spokes ge gen gene gener genera generat generate genrank genstd genvmean gettoken gl gladder gladder_7 glim_l01 glim_l02 glim_l03 glim_l04 glim_l05 glim_l06 glim_l07 glim_l08 glim_l09 glim_l10 glim_l11 glim_l12 glim_lf glim_mu glim_nw1 glim_nw2 glim_nw3 glim_p glim_v1 glim_v2 glim_v3 glim_v4 glim_v5 glim_v6 glim_v7 glm glm_6 glm_p glm_sw glmpred glo glob globa global glogit glogit_8 glogit_p gmeans gnbre_lf gnbreg gnbreg_5 gnbreg_p gomp_lf gompe_sw gomper_p gompertz gompertzhet gomphet_glf gomphet_glf_sh gomphet_gp gomphet_ilf gomphet_ilf_sh gomphet_ip gphdot gphpen gphprint gprefs gprobi_p gprobit gprobit_8 gr gr7 gr_copy gr_current gr_db gr_describe gr_dir gr_draw gr_draw_replay gr_drop gr_edit gr_editviewopts gr_example gr_example2 gr_export gr_print gr_qscheme gr_query gr_read gr_rename gr_replay gr_save gr_set gr_setscheme gr_table gr_undo gr_use graph graph7 grebar greigen greigen_7 greigen_8 grmeanby grmeanby_7 gs_fileinfo gs_filetype gs_graphinfo gs_stat gsort gwood h|0 hadimvo hareg hausman haver he heck_d2 heckma_p heckman heckp_lf heckpr_p heckprob hel help hereg hetpr_lf hetpr_p hetprob hettest hexdump hilite hist hist_7 histogram hlogit hlu hmeans hotel hotelling hprobit hreg hsearch icd9 icd9_ff icd9p iis impute imtest inbase include inf infi infil infile infix inp inpu input ins insheet insp inspe inspec inspect integ inten intreg intreg_7 intreg_p intrg2_ll intrg_ll intrg_ll2 ipolate iqreg ir irf irf_create irfm iri is_svy is_svysum isid istdize ivprob_1_lf ivprob_lf ivprobit ivprobit_p ivreg ivreg_footnote ivtob_1_lf ivtob_lf ivtobit ivtobit_p jackknife jacknife jknife jknife_6 jknife_8 jkstat joinby kalarma1 kap kap_3 kapmeier kappa kapwgt kdensity kdensity_7 keep ksm ksmirnov ktau kwallis l|0 la lab labe label labelbook ladder levels levelsof leverage lfit lfit_p li lincom line linktest lis list lloghet_glf lloghet_glf_sh lloghet_gp lloghet_ilf lloghet_ilf_sh lloghet_ip llogi_sw llogis_p llogist llogistic llogistichet lnorm_lf lnorm_sw lnorma_p lnormal lnormalhet lnormhet_glf lnormhet_glf_sh lnormhet_gp lnormhet_ilf lnormhet_ilf_sh lnormhet_ip lnskew0 loadingplot loc loca local log logi logis_lf logistic logistic_p logit logit_estat logit_p loglogs logrank loneway lookfor lookup lowess lowess_7 lpredict lrecomp lroc lroc_7 lrtest ls lsens lsens_7 lsens_x lstat ltable ltable_7 ltriang lv lvr2plot lvr2plot_7 m|0 ma mac macr macro makecns man manova manova_estat manova_p manovatest mantel mark markin markout marksample mat mat_capp mat_order mat_put_rr mat_rapp mata mata_clear mata_describe mata_drop mata_matdescribe mata_matsave mata_matuse mata_memory mata_mlib mata_mosave mata_rename mata_which matalabel matcproc matlist matname matr matri matrix matrix_input__dlg matstrik mcc mcci md0_ md1_ md1debug_ md2_ md2debug_ mds mds_estat mds_p mdsconfig mdslong mdsmat mdsshepard mdytoe mdytof me_derd mean means median memory memsize meqparse mer merg merge mfp mfx mhelp mhodds minbound mixed_ll mixed_ll_reparm mkassert mkdir mkmat mkspline ml ml_5 ml_adjs ml_bhhhs ml_c_d ml_check ml_clear ml_cnt ml_debug ml_defd ml_e0 ml_e0_bfgs ml_e0_cycle ml_e0_dfp ml_e0i ml_e1 ml_e1_bfgs ml_e1_bhhh ml_e1_cycle ml_e1_dfp ml_e2 ml_e2_cycle ml_ebfg0 ml_ebfr0 ml_ebfr1 ml_ebh0q ml_ebhh0 ml_ebhr0 ml_ebr0i ml_ecr0i ml_edfp0 ml_edfr0 ml_edfr1 ml_edr0i ml_eds ml_eer0i ml_egr0i ml_elf ml_elf_bfgs ml_elf_bhhh ml_elf_cycle ml_elf_dfp ml_elfi ml_elfs ml_enr0i ml_enrr0 ml_erdu0 ml_erdu0_bfgs ml_erdu0_bhhh ml_erdu0_bhhhq ml_erdu0_cycle ml_erdu0_dfp ml_erdu0_nrbfgs ml_exde ml_footnote ml_geqnr ml_grad0 ml_graph ml_hbhhh ml_hd0 ml_hold ml_init ml_inv ml_log ml_max ml_mlout ml_mlout_8 ml_model ml_nb0 ml_opt ml_p ml_plot ml_query ml_rdgrd ml_repor ml_s_e ml_score ml_searc ml_technique ml_unhold mleval mlf_ mlmatbysum mlmatsum mlog mlogi mlogit mlogit_footnote mlogit_p mlopts mlsum mlvecsum mnl0_ mor more mov move mprobit mprobit_lf mprobit_p mrdu0_ mrdu1_ mvdecode mvencode mvreg mvreg_estat n|0 nbreg nbreg_al nbreg_lf nbreg_p nbreg_sw nestreg net newey newey_7 newey_p news nl nl_7 nl_9 nl_9_p nl_p nl_p_7 nlcom nlcom_p nlexp2 nlexp2_7 nlexp2a nlexp2a_7 nlexp3 nlexp3_7 nlgom3 nlgom3_7 nlgom4 nlgom4_7 nlinit nllog3 nllog3_7 nllog4 nllog4_7 nlog_rd nlogit nlogit_p nlogitgen nlogittree nlpred no nobreak noi nois noisi noisil noisily note notes notes_dlg nptrend numlabel numlist odbc old_ver olo olog ologi ologi_sw ologit ologit_p ologitp on one onew onewa oneway op_colnm op_comp op_diff op_inv op_str opr opro oprob oprob_sw oprobi oprobi_p oprobit oprobitp opts_exclusive order orthog orthpoly ou out outf outfi outfil outfile outs outsh outshe outshee outsheet ovtest pac pac_7 palette parse parse_dissim pause pca pca_8 pca_display pca_estat pca_p pca_rotate pcamat pchart pchart_7 pchi pchi_7 pcorr pctile pentium pergram pergram_7 permute permute_8 personal peto_st pkcollapse pkcross pkequiv pkexamine pkexamine_7 pkshape pksumm pksumm_7 pl plo plot plugin pnorm pnorm_7 poisgof poiss_lf poiss_sw poisso_p poisson poisson_estat post postclose postfile postutil pperron pr prais prais_e prais_e2 prais_p predict predictnl preserve print pro prob probi probit probit_estat probit_p proc_time procoverlay procrustes procrustes_estat procrustes_p profiler prog progr progra program prop proportion prtest prtesti pwcorr pwd q\\s qby qbys qchi qchi_7 qladder qladder_7 qnorm qnorm_7 qqplot qqplot_7 qreg qreg_c qreg_p qreg_sw qu quadchk quantile quantile_7 que quer query range ranksum ratio rchart rchart_7 rcof recast reclink recode reg reg3 reg3_p regdw regr regre regre_p2 regres regres_p regress regress_estat regriv_p remap ren rena renam rename renpfix repeat replace report reshape restore ret retu retur return rm rmdir robvar roccomp roccomp_7 roccomp_8 rocf_lf rocfit rocfit_8 rocgold rocplot rocplot_7 roctab roctab_7 rolling rologit rologit_p rot rota rotat rotate rotatemat rreg rreg_p ru run runtest rvfplot rvfplot_7 rvpplot rvpplot_7 sa safesum sample sampsi sav save savedresults saveold sc sca scal scala scalar scatter scm_mine sco scob_lf scob_p scobi_sw scobit scor score scoreplot scoreplot_help scree screeplot screeplot_help sdtest sdtesti se search separate seperate serrbar serrbar_7 serset set set_defaults sfrancia sh she shel shell shewhart shewhart_7 signestimationsample signrank signtest simul simul_7 simulate simulate_8 sktest sleep slogit slogit_d2 slogit_p smooth snapspan so sor sort spearman spikeplot spikeplot_7 spikeplt spline_x split sqreg sqreg_p sret sretu sretur sreturn ssc st st_ct st_hc st_hcd st_hcd_sh st_is st_issys st_note st_promo st_set st_show st_smpl st_subid stack statsby statsby_8 stbase stci stci_7 stcox stcox_estat stcox_fr stcox_fr_ll stcox_p stcox_sw stcoxkm stcoxkm_7 stcstat stcurv stcurve stcurve_7 stdes stem stepwise stereg stfill stgen stir stjoin stmc stmh stphplot stphplot_7 stphtest stphtest_7 stptime strate strate_7 streg streg_sw streset sts sts_7 stset stsplit stsum sttocc sttoct stvary stweib su suest suest_8 sum summ summa summar summari summariz summarize sunflower sureg survcurv survsum svar svar_p svmat svy svy_disp svy_dreg svy_est svy_est_7 svy_estat svy_get svy_gnbreg_p svy_head svy_header svy_heckman_p svy_heckprob_p svy_intreg_p svy_ivreg_p svy_logistic_p svy_logit_p svy_mlogit_p svy_nbreg_p svy_ologit_p svy_oprobit_p svy_poisson_p svy_probit_p svy_regress_p svy_sub svy_sub_7 svy_x svy_x_7 svy_x_p svydes svydes_8 svygen svygnbreg svyheckman svyheckprob svyintreg svyintreg_7 svyintrg svyivreg svylc svylog_p svylogit svymarkout svymarkout_8 svymean svymlog svymlogit svynbreg svyolog svyologit svyoprob svyoprobit svyopts svypois svypois_7 svypoisson svyprobit svyprobt svyprop svyprop_7 svyratio svyreg svyreg_p svyregress svyset svyset_7 svyset_8 svytab svytab_7 svytest svytotal sw sw_8 swcnreg swcox swereg swilk swlogis swlogit swologit swoprbt swpois swprobit swqreg swtobit swweib symmetry symmi symplot symplot_7 syntax sysdescribe sysdir sysuse szroeter ta tab tab1 tab2 tab_or tabd tabdi tabdis tabdisp tabi table tabodds tabodds_7 tabstat tabu tabul tabula tabulat tabulate te tempfile tempname tempvar tes test testnl testparm teststd tetrachoric time_it timer tis tob tobi tobit tobit_p tobit_sw token tokeni tokeniz tokenize tostring total translate translator transmap treat_ll treatr_p treatreg trim trnb_cons trnb_mean trpoiss_d2 trunc_ll truncr_p truncreg tsappend tset tsfill tsline tsline_ex tsreport tsrevar tsrline tsset tssmooth tsunab ttest ttesti tut_chk tut_wait tutorial tw tware_st two twoway twoway__fpfit_serset twoway__function_gen twoway__histogram_gen twoway__ipoint_serset twoway__ipoints_serset twoway__kdensity_gen twoway__lfit_serset twoway__normgen_gen twoway__pci_serset twoway__qfit_serset twoway__scatteri_serset twoway__sunflower_gen twoway_ksm_serset ty typ type typeof u|0 unab unabbrev unabcmd update us use uselabel var var_mkcompanion var_p varbasic varfcast vargranger varirf varirf_add varirf_cgraph varirf_create varirf_ctable varirf_describe varirf_dir varirf_drop varirf_erase varirf_graph varirf_ograph varirf_rename varirf_set varirf_table varlist varlmar varnorm varsoc varstable varstable_w varstable_w2 varwle vce vec vec_fevd vec_mkphi vec_p vec_p_w vecirf_create veclmar veclmar_w vecnorm vecnorm_w vecrank vecstable verinst vers versi versio version view viewsource vif vwls wdatetof webdescribe webseek webuse weib1_lf weib2_lf weib_lf weib_lf0 weibhet_glf weibhet_glf_sh weibhet_glfa weibhet_glfa_sh weibhet_gp weibhet_ilf weibhet_ilf_sh weibhet_ilfa weibhet_ilfa_sh weibhet_ip weibu_sw weibul_p weibull weibull_c weibull_s weibullhet wh whelp whi which whil while wilc_st wilcoxon win wind windo window winexec wntestb wntestb_7 wntestq xchart xchart_7 xcorr xcorr_7 xi xi_6 xmlsav xmlsave xmluse xpose xsh xshe xshel xshell xt_iis xt_tis xtab_p xtabond xtbin_p xtclog xtcloglog xtcloglog_8 xtcloglog_d2 xtcloglog_pa_p xtcloglog_re_p xtcnt_p xtcorr xtdata xtdes xtfront_p xtfrontier xtgee xtgee_elink xtgee_estat xtgee_makeivar xtgee_p xtgee_plink xtgls xtgls_p xthaus xthausman xtht_p xthtaylor xtile xtint_p xtintreg xtintreg_8 xtintreg_d2 xtintreg_p xtivp_1 xtivp_2 xtivreg xtline xtline_ex xtlogit xtlogit_8 xtlogit_d2 xtlogit_fe_p xtlogit_pa_p xtlogit_re_p xtmixed xtmixed_estat xtmixed_p xtnb_fe xtnb_lf xtnbreg xtnbreg_pa_p xtnbreg_refe_p xtpcse xtpcse_p xtpois xtpoisson xtpoisson_d2 xtpoisson_pa_p xtpoisson_refe_p xtpred xtprobit xtprobit_8 xtprobit_d2 xtprobit_re_p xtps_fe xtps_lf xtps_ren xtps_ren_8 xtrar_p xtrc xtrc_p xtrchh xtrefe_p xtreg xtreg_be xtreg_fe xtreg_ml xtreg_pa_p xtreg_re xtregar xtrere_p xtset xtsf_ll xtsf_llti xtsum xttab xttest0 xttobit xttobit_8 xttobit_p xttrans yx yxview__barlike_draw yxview_area_draw yxview_bar_draw yxview_dot_draw yxview_dropline_draw yxview_function_draw yxview_iarrow_draw yxview_ilabels_draw yxview_normal_draw yxview_pcarrow_draw yxview_pcbarrow_draw yxview_pccapsym_draw yxview_pcscatter_draw yxview_pcspike_draw yxview_rarea_draw yxview_rbar_draw yxview_rbarm_draw yxview_rcap_draw yxview_rcapsym_draw yxview_rconnected_draw yxview_rline_draw yxview_rscatter_draw yxview_rspike_draw yxview_spike_draw yxview_sunflower_draw zap_s zinb zinb_llf zinb_plf zip zip_llf zip_p zip_plf zt_ct_5 zt_hc_5 zt_hcd_5 zt_is_5 zt_iss_5 zt_sho_5 zt_smp_5 ztbase_5 ztcox_5 ztdes_5 ztereg_5 ztfill_5 ztgen_5 ztir_5 ztjoin_5 ztnb ztnb_p ztp ztp_p zts_5 ztset_5 ztspli_5 ztsum_5 zttoct_5 ztvary_5 ztweib_5",c:[{cN:"symbol",b:/`[a-zA-Z0-9_]+'/},{cN:"variable",b:/\$\{?[a-zA-Z0-9_]+\}?/},{cN:"string",v:[{b:'`"[^\r\n]*?"\''},{b:'"[^\r\n"]*"'}]},{cN:"built_in",v:[{b:"\\b(abs|acos|asin|atan|atan2|atanh|ceil|cloglog|comb|cos|digamma|exp|floor|invcloglog|invlogit|ln|lnfact|lnfactorial|lngamma|log|log10|max|min|mod|reldif|round|sign|sin|sqrt|sum|tan|tanh|trigamma|trunc|betaden|Binomial|binorm|binormal|chi2|chi2tail|dgammapda|dgammapdada|dgammapdadx|dgammapdx|dgammapdxdx|F|Fden|Ftail|gammaden|gammap|ibeta|invbinomial|invchi2|invchi2tail|invF|invFtail|invgammap|invibeta|invnchi2|invnFtail|invnibeta|invnorm|invnormal|invttail|nbetaden|nchi2|nFden|nFtail|nibeta|norm|normal|normalden|normd|npnchi2|tden|ttail|uniform|abbrev|char|index|indexnot|length|lower|ltrim|match|plural|proper|real|regexm|regexr|regexs|reverse|rtrim|string|strlen|strlower|strltrim|strmatch|strofreal|strpos|strproper|strreverse|strrtrim|strtrim|strupper|subinstr|subinword|substr|trim|upper|word|wordcount|_caller|autocode|byteorder|chop|clip|cond|e|epsdouble|epsfloat|group|inlist|inrange|irecode|matrix|maxbyte|maxdouble|maxfloat|maxint|maxlong|mi|minbyte|mindouble|minfloat|minint|minlong|missing|r|recode|replay|return|s|scalar|d|date|day|dow|doy|halfyear|mdy|month|quarter|week|year|d|daily|dofd|dofh|dofm|dofq|dofw|dofy|h|halfyearly|hofd|m|mofd|monthly|q|qofd|quarterly|tin|twithin|w|weekly|wofd|y|yearly|yh|ym|yofd|yq|yw|cholesky|colnumb|colsof|corr|det|diag|diag0cnt|el|get|hadamard|I|inv|invsym|issym|issymmetric|J|matmissing|matuniform|mreldif|nullmat|rownumb|rowsof|sweep|syminv|trace|vec|vecdiag)(?=\\(|$)"}]},e.C("^[ ]*\\*.*$",!1),e.CLCM,e.CBCM]}});hljs.registerLanguage("julia",function(e){var r={keyword:"in isa where baremodule begin break catch ccall const continue do else elseif end export false finally for function global if import importall let local macro module quote return true try using while type immutable abstract bitstype typealias ",literal:"true false ARGS C_NULL DevNull ENDIAN_BOM ENV I Inf Inf16 Inf32 Inf64 InsertionSort JULIA_HOME LOAD_PATH MergeSort NaN NaN16 NaN32 NaN64 PROGRAM_FILE QuickSort RoundDown RoundFromZero RoundNearest RoundNearestTiesAway RoundNearestTiesUp RoundToZero RoundUp STDERR STDIN STDOUT VERSION catalan e|0 eu|0 eulergamma golden im nothing pi γ π φ ",built_in:"ANY AbstractArray AbstractChannel AbstractFloat AbstractMatrix AbstractRNG AbstractSerializer AbstractSet AbstractSparseArray AbstractSparseMatrix AbstractSparseVector AbstractString AbstractUnitRange AbstractVecOrMat AbstractVector Any ArgumentError Array AssertionError Associative Base64DecodePipe Base64EncodePipe Bidiagonal BigFloat BigInt BitArray BitMatrix BitVector Bool BoundsError BufferStream CachingPool CapturedException CartesianIndex CartesianRange Cchar Cdouble Cfloat Channel Char Cint Cintmax_t Clong Clonglong ClusterManager Cmd CodeInfo Colon Complex Complex128 Complex32 Complex64 CompositeException Condition ConjArray ConjMatrix ConjVector Cptrdiff_t Cshort Csize_t Cssize_t Cstring Cuchar Cuint Cuintmax_t Culong Culonglong Cushort Cwchar_t Cwstring DataType Date DateFormat DateTime DenseArray DenseMatrix DenseVecOrMat DenseVector Diagonal Dict DimensionMismatch Dims DirectIndexString Display DivideError DomainError EOFError EachLine Enum Enumerate ErrorException Exception ExponentialBackOff Expr Factorization FileMonitor Float16 Float32 Float64 Function Future GlobalRef GotoNode HTML Hermitian IO IOBuffer IOContext IOStream IPAddr IPv4 IPv6 IndexCartesian IndexLinear IndexStyle InexactError InitError Int Int128 Int16 Int32 Int64 Int8 IntSet Integer InterruptException InvalidStateException Irrational KeyError LabelNode LinSpace LineNumberNode LoadError LowerTriangular MIME Matrix MersenneTwister Method MethodError MethodTable Module NTuple NewvarNode NullException Nullable Number ObjectIdDict OrdinalRange OutOfMemoryError OverflowError Pair ParseError PartialQuickSort PermutedDimsArray Pipe PollingFileWatcher ProcessExitedException Ptr QuoteNode RandomDevice Range RangeIndex Rational RawFD ReadOnlyMemoryError Real ReentrantLock Ref Regex RegexMatch RemoteChannel RemoteException RevString RoundingMode RowVector SSAValue SegmentationFault SerializationState Set SharedArray SharedMatrix SharedVector Signed SimpleVector Slot SlotNumber SparseMatrixCSC SparseVector StackFrame StackOverflowError StackTrace StepRange StepRangeLen StridedArray StridedMatrix StridedVecOrMat StridedVector String SubArray SubString SymTridiagonal Symbol Symmetric SystemError TCPSocket Task Text TextDisplay Timer Tridiagonal Tuple Type TypeError TypeMapEntry TypeMapLevel TypeName TypeVar TypedSlot UDPSocket UInt UInt128 UInt16 UInt32 UInt64 UInt8 UndefRefError UndefVarError UnicodeError UniformScaling Union UnionAll UnitRange Unsigned UpperTriangular Val Vararg VecElement VecOrMat Vector VersionNumber Void WeakKeyDict WeakRef WorkerConfig WorkerPool "},t="[A-Za-z_\\u00A1-\\uFFFF][A-Za-z_0-9\\u00A1-\\uFFFF]*",a={l:t,k:r,i:/<\//},n={cN:"number",b:/(\b0x[\d_]*(\.[\d_]*)?|0x\.\d[\d_]*)p[-+]?\d+|\b0[box][a-fA-F0-9][a-fA-F0-9_]*|(\b\d[\d_]*(\.[\d_]*)?|\.\d[\d_]*)([eEfF][-+]?\d+)?/,r:0},o={cN:"string",b:/'(.|\\[xXuU][a-zA-Z0-9]+)'/},i={cN:"subst",b:/\$\(/,e:/\)/,k:r},l={cN:"variable",b:"\\$"+t},c={cN:"string",c:[e.BE,i,l],v:[{b:/\w*"""/,e:/"""\w*/,r:10},{b:/\w*"/,e:/"\w*/}]},s={cN:"string",c:[e.BE,i,l],b:"`",e:"`"},d={cN:"meta",b:"@"+t},u={cN:"comment",v:[{b:"#=",e:"=#",r:10},{b:"#",e:"$"}]};return a.c=[n,o,c,s,d,u,e.HCM,{cN:"keyword",b:"\\b(((abstract|primitive)\\s+)type|(mutable\\s+)?struct)\\b"},{b:/<:/}],i.c=a.c,a});hljs.registerLanguage("sml",function(e){return{aliases:["ml"],k:{keyword:"abstype and andalso as case datatype do else end eqtype exception fn fun functor handle if in include infix infixr let local nonfix of op open orelse raise rec sharing sig signature struct structure then type val with withtype where while",built_in:"array bool char exn int list option order real ref string substring vector unit word",literal:"true false NONE SOME LESS EQUAL GREATER nil"},i:/\/\/|>>/,l:"[a-z_]\\w*!?",c:[{cN:"literal",b:/\[(\|\|)?\]|\(\)/,r:0},e.C("\\(\\*","\\*\\)",{c:["self"]}),{cN:"symbol",b:"'[A-Za-z_](?!')[\\w']*"},{cN:"type",b:"`[A-Z][\\w']*"},{cN:"type",b:"\\b[A-Z][\\w']*",r:0},{b:"[a-z_]\\w*'[\\w']*"},e.inherit(e.ASM,{cN:"string",r:0}),e.inherit(e.QSM,{i:null}),{cN:"number",b:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",r:0},{b:/[-=]>/}]}});hljs.registerLanguage("cs",function(e){var i={keyword:"abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long nameof object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let on orderby partial remove select set value var where yield",literal:"null false true"},t={cN:"string",b:'@"',e:'"',c:[{b:'""'}]},r=e.inherit(t,{i:/\n/}),a={cN:"subst",b:"{",e:"}",k:i},c=e.inherit(a,{i:/\n/}),n={cN:"string",b:/\$"/,e:'"',i:/\n/,c:[{b:"{{"},{b:"}}"},e.BE,c]},s={cN:"string",b:/\$@"/,e:'"',c:[{b:"{{"},{b:"}}"},{b:'""'},a]},o=e.inherit(s,{i:/\n/,c:[{b:"{{"},{b:"}}"},{b:'""'},c]});a.c=[s,n,t,e.ASM,e.QSM,e.CNM,e.CBCM],c.c=[o,n,r,e.ASM,e.QSM,e.CNM,e.inherit(e.CBCM,{i:/\n/})];var l={v:[s,n,t,e.ASM,e.QSM]},b=e.IR+"(<"+e.IR+"(\\s*,\\s*"+e.IR+")*>)?(\\[\\])?";return{aliases:["csharp"],k:i,i:/::/,c:[e.C("///","$",{rB:!0,c:[{cN:"doctag",v:[{b:"///",r:0},{b:""},{b:""}]}]}),e.CLCM,e.CBCM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},l,e.CNM,{bK:"class interface",e:/[{;=]/,i:/[^\s:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"namespace",e:/[{;=]/,i:/[^\s:]/,c:[e.inherit(e.TM,{b:"[a-zA-Z](\\.?\\w)*"}),e.CLCM,e.CBCM]},{cN:"meta",b:"^\\s*\\[",eB:!0,e:"\\]",eE:!0,c:[{cN:"meta-string",b:/"/,e:/"/}]},{bK:"new return throw await else",r:0},{cN:"function",b:"("+b+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:i,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:i,r:0,c:[l,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}});hljs.registerLanguage("tcl",function(e){return{aliases:["tk"],k:"after append apply array auto_execok auto_import auto_load auto_mkindex auto_mkindex_old auto_qualify auto_reset bgerror binary break catch cd chan clock close concat continue dde dict encoding eof error eval exec exit expr fblocked fconfigure fcopy file fileevent filename flush for foreach format gets glob global history http if incr info interp join lappend|10 lassign|10 lindex|10 linsert|10 list llength|10 load lrange|10 lrepeat|10 lreplace|10 lreverse|10 lsearch|10 lset|10 lsort|10 mathfunc mathop memory msgcat namespace open package parray pid pkg::create pkg_mkIndex platform platform::shell proc puts pwd read refchan regexp registry regsub|10 rename return safe scan seek set socket source split string subst switch tcl_endOfWord tcl_findLibrary tcl_startOfNextWord tcl_startOfPreviousWord tcl_wordBreakAfter tcl_wordBreakBefore tcltest tclvars tell time tm trace unknown unload unset update uplevel upvar variable vwait while",c:[e.C(";[ \\t]*#","$"),e.C("^[ \\t]*#","$"),{bK:"proc",e:"[\\{]",eE:!0,c:[{cN:"title",b:"[ \\t\\n\\r]+(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*",e:"[ \\t\\n\\r]",eW:!0,eE:!0}]},{eE:!0,v:[{b:"\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*\\(([a-zA-Z0-9_])*\\)",e:"[^a-zA-Z0-9_\\}\\$]"},{b:"\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*",e:"(\\))?[^a-zA-Z0-9_\\}\\$]"}]},{cN:"string",c:[e.BE],v:[e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},{cN:"number",v:[e.BNM,e.CNM]}]}});hljs.registerLanguage("csp",function(r){return{cI:!1,l:"[a-zA-Z][a-zA-Z0-9_-]*",k:{keyword:"base-uri child-src connect-src default-src font-src form-action frame-ancestors frame-src img-src media-src object-src plugin-types report-uri sandbox script-src style-src"},c:[{cN:"string",b:"'",e:"'"},{cN:"attribute",b:"^Content",e:":",eE:!0}]}});hljs.registerLanguage("rib",function(e){return{k:"ArchiveRecord AreaLightSource Atmosphere Attribute AttributeBegin AttributeEnd Basis Begin Blobby Bound Clipping ClippingPlane Color ColorSamples ConcatTransform Cone CoordinateSystem CoordSysTransform CropWindow Curves Cylinder DepthOfField Detail DetailRange Disk Displacement Display End ErrorHandler Exposure Exterior Format FrameAspectRatio FrameBegin FrameEnd GeneralPolygon GeometricApproximation Geometry Hider Hyperboloid Identity Illuminate Imager Interior LightSource MakeCubeFaceEnvironment MakeLatLongEnvironment MakeShadow MakeTexture Matte MotionBegin MotionEnd NuPatch ObjectBegin ObjectEnd ObjectInstance Opacity Option Orientation Paraboloid Patch PatchMesh Perspective PixelFilter PixelSamples PixelVariance Points PointsGeneralPolygons PointsPolygons Polygon Procedural Projection Quantize ReadArchive RelativeDetail ReverseOrientation Rotate Scale ScreenWindow ShadingInterpolation ShadingRate Shutter Sides Skew SolidBegin SolidEnd Sphere SubdivisionMesh Surface TextureCoordinates Torus Transform TransformBegin TransformEnd TransformPoints Translate TrimCurve WorldBegin WorldEnd",i:"",e:",\\s+",rB:!0,eW:!0,c:[{cN:"attr",b:":\\w+"},s.ASM,s.QSM,{b:"\\w+",r:0}]}]},{b:"\\(\\s*",e:"\\s*\\)",eE:!0,c:[{b:"\\w+\\s*=",e:"\\s+",rB:!0,eW:!0,c:[{cN:"attr",b:"\\w+",r:0},s.ASM,s.QSM,{b:"\\w+",r:0}]}]}]},{b:"^\\s*[=~]\\s*"},{b:"#{",starts:{e:"}",sL:"ruby"}}]}});hljs.registerLanguage("dos",function(e){var r=e.C(/^\s*@?rem\b/,/$/,{r:10}),t={cN:"symbol",b:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)",r:0};return{aliases:["bat","cmd"],cI:!0,i:/\/\*/,k:{keyword:"if else goto for in do call exit not exist errorlevel defined equ neq lss leq gtr geq",built_in:"prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux shift cd dir echo setlocal endlocal set pause copy append assoc at attrib break cacls cd chcp chdir chkdsk chkntfs cls cmd color comp compact convert date dir diskcomp diskcopy doskey erase fs find findstr format ftype graftabl help keyb label md mkdir mode more move path pause print popd pushd promt rd recover rem rename replace restore rmdir shiftsort start subst time title tree type ver verify vol ping net ipconfig taskkill xcopy ren del"},c:[{cN:"variable",b:/%%[^ ]|%[^ ]+?%|![^ ]+?!/},{cN:"function",b:t.b,e:"goto:eof",c:[e.inherit(e.TM,{b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),r]},{cN:"number",b:"\\b\\d+",r:0},r]}});hljs.registerLanguage("objectivec",function(e){var t={cN:"built_in",b:"\\b(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)\\w+"},_={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},i=/[a-zA-Z@][a-zA-Z0-9_]*/,n="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],k:_,l:i,i:""}]}]},{cN:"class",b:"("+n.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:n,l:i,c:[e.UTM]},{b:"\\."+e.UIR,r:0}]}});hljs.registerLanguage("tex",function(c){var e={cN:"tag",b:/\\/,r:0,c:[{cN:"name",v:[{b:/[a-zA-Zа-яА-я]+[*]?/},{b:/[^a-zA-Zа-яА-я0-9]/}],starts:{eW:!0,r:0,c:[{cN:"string",v:[{b:/\[/,e:/\]/},{b:/\{/,e:/\}/}]},{b:/\s*=\s*/,eW:!0,r:0,c:[{cN:"number",b:/-?\d*\.?\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?/}]}]}}]};return{c:[e,{cN:"formula",c:[e],r:0,v:[{b:/\$\$/,e:/\$\$/},{b:/\$/,e:/\$/}]},c.C("%","$",{r:0})]}});hljs.registerLanguage("purebasic",function(e){var r={cN:"string",b:'(~)?"',e:'"',i:"\\n"},t={cN:"symbol",b:"#[a-zA-Z_]\\w*\\$?"};return{aliases:["pb","pbi"],k:"And As Break CallDebugger Case CompilerCase CompilerDefault CompilerElse CompilerEndIf CompilerEndSelect CompilerError CompilerIf CompilerSelect Continue Data DataSection EndDataSection Debug DebugLevel Default Define Dim DisableASM DisableDebugger DisableExplicit Else ElseIf EnableASM EnableDebugger EnableExplicit End EndEnumeration EndIf EndImport EndInterface EndMacro EndProcedure EndSelect EndStructure EndStructureUnion EndWith Enumeration Extends FakeReturn For Next ForEach ForEver Global Gosub Goto If Import ImportC IncludeBinary IncludeFile IncludePath Interface Macro NewList Not Or ProcedureReturn Protected Prototype PrototypeC Read ReDim Repeat Until Restore Return Select Shared Static Step Structure StructureUnion Swap To Wend While With XIncludeFile XOr Procedure ProcedureC ProcedureCDLL ProcedureDLL Declare DeclareC DeclareCDLL DeclareDLL",c:[e.C(";","$",{r:0}),{cN:"function",b:"\\b(Procedure|Declare)(C|CDLL|DLL)?\\b",e:"\\(",eE:!0,rB:!0,c:[{cN:"keyword",b:"(Procedure|Declare)(C|CDLL|DLL)?",eE:!0},{cN:"type",b:"\\.\\w*"},e.UTM]},r,t]}});hljs.registerLanguage("clojure",function(e){var t={"builtin-name":"def defonce cond apply if-not if-let if not not= = < > <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for dosync and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time re-find re-groups rand-int rand mod locking assert-valid-fdecl alias resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! to-array future future-call into-array aset gen-class reduce map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"},r="a-zA-Z_\\-!.?+*=<>&#'",n="["+r+"]["+r+"0-9/;:]*",a="[-+]?\\d+(\\.\\d+)?",o={b:n,r:0},s={cN:"number",b:a,r:0},c=e.inherit(e.QSM,{i:null}),i=e.C(";","$",{r:0}),d={cN:"literal",b:/\b(true|false|nil)\b/},l={b:"[\\[\\{]",e:"[\\]\\}]"},m={cN:"comment",b:"\\^"+n},p=e.C("\\^\\{","\\}"),u={cN:"symbol",b:"[:]{1,2}"+n},f={b:"\\(",e:"\\)"},h={eW:!0,r:0},y={k:t,l:n,cN:"name",b:n,starts:h},b=[f,c,m,p,i,u,l,s,d,o];return f.c=[e.C("comment",""),y,h],h.c=b,l.c=b,p.c=[l],{aliases:["clj"],i:/\S/,c:[f,c,m,p,i,u,l,s,d]}});hljs.registerLanguage("clojure-repl",function(e){return{c:[{cN:"meta",b:/^([\w.-]+|\s*#_)=>/,starts:{e:/$/,sL:"clojure"}}]}});hljs.registerLanguage("clean",function(e){return{aliases:["clean","icl","dcl"],k:{keyword:"if let in with where case of class instance otherwise implementation definition system module from import qualified as special code inline foreign export ccall stdcall generic derive infix infixl infixr",literal:"True False"},c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.CNM,{b:"->|<-[|:]?|::|#!?|>>=|\\{\\||\\|\\}|:==|=:|\\.\\.|<>|`"}]}});hljs.registerLanguage("n1ql",function(e){return{cI:!0,c:[{bK:"build create index delete drop explain infer|10 insert merge prepare select update upsert|10",e:/;/,eW:!0,k:{keyword:"all alter analyze and any array as asc begin between binary boolean break bucket build by call case cast cluster collate collection commit connect continue correlate cover create database dataset datastore declare decrement delete derived desc describe distinct do drop each element else end every except exclude execute exists explain fetch first flatten for force from function grant group gsi having if ignore ilike in include increment index infer inline inner insert intersect into is join key keys keyspace known last left let letting like limit lsm map mapping matched materialized merge minus namespace nest not number object offset on option or order outer over parse partition password path pool prepare primary private privilege procedure public raw realm reduce rename return returning revoke right role rollback satisfies schema select self semi set show some start statistics string system then to transaction trigger truncate under union unique unknown unnest unset update upsert use user using validate value valued values via view when where while with within work xor",literal:"true false null missing|5",built_in:"array_agg array_append array_concat array_contains array_count array_distinct array_ifnull array_length array_max array_min array_position array_prepend array_put array_range array_remove array_repeat array_replace array_reverse array_sort array_sum avg count max min sum greatest least ifmissing ifmissingornull ifnull missingif nullif ifinf ifnan ifnanorinf naninf neginfif posinfif clock_millis clock_str date_add_millis date_add_str date_diff_millis date_diff_str date_part_millis date_part_str date_trunc_millis date_trunc_str duration_to_str millis str_to_millis millis_to_str millis_to_utc millis_to_zone_name now_millis now_str str_to_duration str_to_utc str_to_zone_name decode_json encode_json encoded_size poly_length base64 base64_encode base64_decode meta uuid abs acos asin atan atan2 ceil cos degrees e exp ln log floor pi power radians random round sign sin sqrt tan trunc object_length object_names object_pairs object_inner_pairs object_values object_inner_values object_add object_put object_remove object_unwrap regexp_contains regexp_like regexp_position regexp_replace contains initcap length lower ltrim position repeat replace rtrim split substr title trim upper isarray isatom isboolean isnumber isobject isstring type toarray toatom toboolean tonumber toobject tostring"},c:[{cN:"string",b:"'",e:"'",c:[e.BE],r:0},{cN:"string",b:'"',e:'"',c:[e.BE],r:0},{cN:"symbol",b:"`",e:"`",c:[e.BE],r:2},e.CNM,e.CBCM]},e.CBCM]}});hljs.registerLanguage("lsl",function(E){var T={cN:"subst",b:/\\[tn"\\]/},e={cN:"string",b:'"',e:'"',c:[T]},A={cN:"number",b:E.CNR},R={cN:"literal",v:[{b:"\\b(?:PI|TWO_PI|PI_BY_TWO|DEG_TO_RAD|RAD_TO_DEG|SQRT2)\\b"},{b:"\\b(?:XP_ERROR_(?:EXPERIENCES_DISABLED|EXPERIENCE_(?:DISABLED|SUSPENDED)|INVALID_(?:EXPERIENCE|PARAMETERS)|KEY_NOT_FOUND|MATURITY_EXCEEDED|NONE|NOT_(?:FOUND|PERMITTED(?:_LAND)?)|NO_EXPERIENCE|QUOTA_EXCEEDED|RETRY_UPDATE|STORAGE_EXCEPTION|STORE_DISABLED|THROTTLED|UNKNOWN_ERROR)|JSON_APPEND|STATUS_(?:PHYSICS|ROTATE_[XYZ]|PHANTOM|SANDBOX|BLOCK_GRAB(?:_OBJECT)?|(?:DIE|RETURN)_AT_EDGE|CAST_SHADOWS|OK|MALFORMED_PARAMS|TYPE_MISMATCH|BOUNDS_ERROR|NOT_(?:FOUND|SUPPORTED)|INTERNAL_ERROR|WHITELIST_FAILED)|AGENT(?:_(?:BY_(?:LEGACY_|USER)NAME|FLYING|ATTACHMENTS|SCRIPTED|MOUSELOOK|SITTING|ON_OBJECT|AWAY|WALKING|IN_AIR|TYPING|CROUCHING|BUSY|ALWAYS_RUN|AUTOPILOT|LIST_(?:PARCEL(?:_OWNER)?|REGION)))?|CAMERA_(?:PITCH|DISTANCE|BEHINDNESS_(?:ANGLE|LAG)|(?:FOCUS|POSITION)(?:_(?:THRESHOLD|LOCKED|LAG))?|FOCUS_OFFSET|ACTIVE)|ANIM_ON|LOOP|REVERSE|PING_PONG|SMOOTH|ROTATE|SCALE|ALL_SIDES|LINK_(?:ROOT|SET|ALL_(?:OTHERS|CHILDREN)|THIS)|ACTIVE|PASS(?:IVE|_(?:ALWAYS|IF_NOT_HANDLED|NEVER))|SCRIPTED|CONTROL_(?:FWD|BACK|(?:ROT_)?(?:LEFT|RIGHT)|UP|DOWN|(?:ML_)?LBUTTON)|PERMISSION_(?:RETURN_OBJECTS|DEBIT|OVERRIDE_ANIMATIONS|SILENT_ESTATE_MANAGEMENT|TAKE_CONTROLS|TRIGGER_ANIMATION|ATTACH|CHANGE_LINKS|(?:CONTROL|TRACK)_CAMERA|TELEPORT)|INVENTORY_(?:TEXTURE|SOUND|OBJECT|SCRIPT|LANDMARK|CLOTHING|NOTECARD|BODYPART|ANIMATION|GESTURE|ALL|NONE)|CHANGED_(?:INVENTORY|COLOR|SHAPE|SCALE|TEXTURE|LINK|ALLOWED_DROP|OWNER|REGION(?:_START)?|TELEPORT|MEDIA)|OBJECT_(?:CLICK_ACTION|HOVER_HEIGHT|LAST_OWNER_ID|(?:PHYSICS|SERVER|STREAMING)_COST|UNKNOWN_DETAIL|CHARACTER_TIME|PHANTOM|PHYSICS|TEMP_ON_REZ|NAME|DESC|POS|PRIM_(?:COUNT|EQUIVALENCE)|RETURN_(?:PARCEL(?:_OWNER)?|REGION)|REZZER_KEY|ROO?T|VELOCITY|OMEGA|OWNER|GROUP|CREATOR|ATTACHED_POINT|RENDER_WEIGHT|(?:BODY_SHAPE|PATHFINDING)_TYPE|(?:RUNNING|TOTAL)_SCRIPT_COUNT|TOTAL_INVENTORY_COUNT|SCRIPT_(?:MEMORY|TIME))|TYPE_(?:INTEGER|FLOAT|STRING|KEY|VECTOR|ROTATION|INVALID)|(?:DEBUG|PUBLIC)_CHANNEL|ATTACH_(?:AVATAR_CENTER|CHEST|HEAD|BACK|PELVIS|MOUTH|CHIN|NECK|NOSE|BELLY|[LR](?:SHOULDER|HAND|FOOT|EAR|EYE|[UL](?:ARM|LEG)|HIP)|(?:LEFT|RIGHT)_PEC|HUD_(?:CENTER_[12]|TOP_(?:RIGHT|CENTER|LEFT)|BOTTOM(?:_(?:RIGHT|LEFT))?)|[LR]HAND_RING1|TAIL_(?:BASE|TIP)|[LR]WING|FACE_(?:JAW|[LR]EAR|[LR]EYE|TOUNGE)|GROIN|HIND_[LR]FOOT)|LAND_(?:LEVEL|RAISE|LOWER|SMOOTH|NOISE|REVERT)|DATA_(?:ONLINE|NAME|BORN|SIM_(?:POS|STATUS|RATING)|PAYINFO)|PAYMENT_INFO_(?:ON_FILE|USED)|REMOTE_DATA_(?:CHANNEL|REQUEST|REPLY)|PSYS_(?:PART_(?:BF_(?:ZERO|ONE(?:_MINUS_(?:DEST_COLOR|SOURCE_(ALPHA|COLOR)))?|DEST_COLOR|SOURCE_(ALPHA|COLOR))|BLEND_FUNC_(DEST|SOURCE)|FLAGS|(?:START|END)_(?:COLOR|ALPHA|SCALE|GLOW)|MAX_AGE|(?:RIBBON|WIND|INTERP_(?:COLOR|SCALE)|BOUNCE|FOLLOW_(?:SRC|VELOCITY)|TARGET_(?:POS|LINEAR)|EMISSIVE)_MASK)|SRC_(?:MAX_AGE|PATTERN|ANGLE_(?:BEGIN|END)|BURST_(?:RATE|PART_COUNT|RADIUS|SPEED_(?:MIN|MAX))|ACCEL|TEXTURE|TARGET_KEY|OMEGA|PATTERN_(?:DROP|EXPLODE|ANGLE(?:_CONE(?:_EMPTY)?)?)))|VEHICLE_(?:REFERENCE_FRAME|TYPE_(?:NONE|SLED|CAR|BOAT|AIRPLANE|BALLOON)|(?:LINEAR|ANGULAR)_(?:FRICTION_TIMESCALE|MOTOR_DIRECTION)|LINEAR_MOTOR_OFFSET|HOVER_(?:HEIGHT|EFFICIENCY|TIMESCALE)|BUOYANCY|(?:LINEAR|ANGULAR)_(?:DEFLECTION_(?:EFFICIENCY|TIMESCALE)|MOTOR_(?:DECAY_)?TIMESCALE)|VERTICAL_ATTRACTION_(?:EFFICIENCY|TIMESCALE)|BANKING_(?:EFFICIENCY|MIX|TIMESCALE)|FLAG_(?:NO_DEFLECTION_UP|LIMIT_(?:ROLL_ONLY|MOTOR_UP)|HOVER_(?:(?:WATER|TERRAIN|UP)_ONLY|GLOBAL_HEIGHT)|MOUSELOOK_(?:STEER|BANK)|CAMERA_DECOUPLED))|PRIM_(?:ALPHA_MODE(?:_(?:BLEND|EMISSIVE|MASK|NONE))?|NORMAL|SPECULAR|TYPE(?:_(?:BOX|CYLINDER|PRISM|SPHERE|TORUS|TUBE|RING|SCULPT))?|HOLE_(?:DEFAULT|CIRCLE|SQUARE|TRIANGLE)|MATERIAL(?:_(?:STONE|METAL|GLASS|WOOD|FLESH|PLASTIC|RUBBER))?|SHINY_(?:NONE|LOW|MEDIUM|HIGH)|BUMP_(?:NONE|BRIGHT|DARK|WOOD|BARK|BRICKS|CHECKER|CONCRETE|TILE|STONE|DISKS|GRAVEL|BLOBS|SIDING|LARGETILE|STUCCO|SUCTION|WEAVE)|TEXGEN_(?:DEFAULT|PLANAR)|SCULPT_(?:TYPE_(?:SPHERE|TORUS|PLANE|CYLINDER|MASK)|FLAG_(?:MIRROR|INVERT))|PHYSICS(?:_(?:SHAPE_(?:CONVEX|NONE|PRIM|TYPE)))?|(?:POS|ROT)_LOCAL|SLICE|TEXT|FLEXIBLE|POINT_LIGHT|TEMP_ON_REZ|PHANTOM|POSITION|SIZE|ROTATION|TEXTURE|NAME|OMEGA|DESC|LINK_TARGET|COLOR|BUMP_SHINY|FULLBRIGHT|TEXGEN|GLOW|MEDIA_(?:ALT_IMAGE_ENABLE|CONTROLS|(?:CURRENT|HOME)_URL|AUTO_(?:LOOP|PLAY|SCALE|ZOOM)|FIRST_CLICK_INTERACT|(?:WIDTH|HEIGHT)_PIXELS|WHITELIST(?:_ENABLE)?|PERMS_(?:INTERACT|CONTROL)|PARAM_MAX|CONTROLS_(?:STANDARD|MINI)|PERM_(?:NONE|OWNER|GROUP|ANYONE)|MAX_(?:URL_LENGTH|WHITELIST_(?:SIZE|COUNT)|(?:WIDTH|HEIGHT)_PIXELS)))|MASK_(?:BASE|OWNER|GROUP|EVERYONE|NEXT)|PERM_(?:TRANSFER|MODIFY|COPY|MOVE|ALL)|PARCEL_(?:MEDIA_COMMAND_(?:STOP|PAUSE|PLAY|LOOP|TEXTURE|URL|TIME|AGENT|UNLOAD|AUTO_ALIGN|TYPE|SIZE|DESC|LOOP_SET)|FLAG_(?:ALLOW_(?:FLY|(?:GROUP_)?SCRIPTS|LANDMARK|TERRAFORM|DAMAGE|CREATE_(?:GROUP_)?OBJECTS)|USE_(?:ACCESS_(?:GROUP|LIST)|BAN_LIST|LAND_PASS_LIST)|LOCAL_SOUND_ONLY|RESTRICT_PUSHOBJECT|ALLOW_(?:GROUP|ALL)_OBJECT_ENTRY)|COUNT_(?:TOTAL|OWNER|GROUP|OTHER|SELECTED|TEMP)|DETAILS_(?:NAME|DESC|OWNER|GROUP|AREA|ID|SEE_AVATARS))|LIST_STAT_(?:MAX|MIN|MEAN|MEDIAN|STD_DEV|SUM(?:_SQUARES)?|NUM_COUNT|GEOMETRIC_MEAN|RANGE)|PAY_(?:HIDE|DEFAULT)|REGION_FLAG_(?:ALLOW_DAMAGE|FIXED_SUN|BLOCK_TERRAFORM|SANDBOX|DISABLE_(?:COLLISIONS|PHYSICS)|BLOCK_FLY|ALLOW_DIRECT_TELEPORT|RESTRICT_PUSHOBJECT)|HTTP_(?:METHOD|MIMETYPE|BODY_(?:MAXLENGTH|TRUNCATED)|CUSTOM_HEADER|PRAGMA_NO_CACHE|VERBOSE_THROTTLE|VERIFY_CERT)|STRING_(?:TRIM(?:_(?:HEAD|TAIL))?)|CLICK_ACTION_(?:NONE|TOUCH|SIT|BUY|PAY|OPEN(?:_MEDIA)?|PLAY|ZOOM)|TOUCH_INVALID_FACE|PROFILE_(?:NONE|SCRIPT_MEMORY)|RC_(?:DATA_FLAGS|DETECT_PHANTOM|GET_(?:LINK_NUM|NORMAL|ROOT_KEY)|MAX_HITS|REJECT_(?:TYPES|AGENTS|(?:NON)?PHYSICAL|LAND))|RCERR_(?:CAST_TIME_EXCEEDED|SIM_PERF_LOW|UNKNOWN)|ESTATE_ACCESS_(?:ALLOWED_(?:AGENT|GROUP)_(?:ADD|REMOVE)|BANNED_AGENT_(?:ADD|REMOVE))|DENSITY|FRICTION|RESTITUTION|GRAVITY_MULTIPLIER|KFM_(?:COMMAND|CMD_(?:PLAY|STOP|PAUSE)|MODE|FORWARD|LOOP|PING_PONG|REVERSE|DATA|ROTATION|TRANSLATION)|ERR_(?:GENERIC|PARCEL_PERMISSIONS|MALFORMED_PARAMS|RUNTIME_PERMISSIONS|THROTTLED)|CHARACTER_(?:CMD_(?:(?:SMOOTH_)?STOP|JUMP)|DESIRED_(?:TURN_)?SPEED|RADIUS|STAY_WITHIN_PARCEL|LENGTH|ORIENTATION|ACCOUNT_FOR_SKIPPED_FRAMES|AVOIDANCE_MODE|TYPE(?:_(?:[ABCD]|NONE))?|MAX_(?:DECEL|TURN_RADIUS|(?:ACCEL|SPEED)))|PURSUIT_(?:OFFSET|FUZZ_FACTOR|GOAL_TOLERANCE|INTERCEPT)|REQUIRE_LINE_OF_SIGHT|FORCE_DIRECT_PATH|VERTICAL|HORIZONTAL|AVOID_(?:CHARACTERS|DYNAMIC_OBSTACLES|NONE)|PU_(?:EVADE_(?:HIDDEN|SPOTTED)|FAILURE_(?:DYNAMIC_PATHFINDING_DISABLED|INVALID_(?:GOAL|START)|NO_(?:NAVMESH|VALID_DESTINATION)|OTHER|TARGET_GONE|(?:PARCEL_)?UNREACHABLE)|(?:GOAL|SLOWDOWN_DISTANCE)_REACHED)|TRAVERSAL_TYPE(?:_(?:FAST|NONE|SLOW))?|CONTENT_TYPE_(?:ATOM|FORM|HTML|JSON|LLSD|RSS|TEXT|XHTML|XML)|GCNP_(?:RADIUS|STATIC)|(?:PATROL|WANDER)_PAUSE_AT_WAYPOINTS|OPT_(?:AVATAR|CHARACTER|EXCLUSION_VOLUME|LEGACY_LINKSET|MATERIAL_VOLUME|OTHER|STATIC_OBSTACLE|WALKABLE)|SIM_STAT_PCT_CHARS_STEPPED)\\b"},{b:"\\b(?:FALSE|TRUE)\\b"},{b:"\\b(?:ZERO_ROTATION)\\b"},{b:"\\b(?:EOF|JSON_(?:ARRAY|DELETE|FALSE|INVALID|NULL|NUMBER|OBJECT|STRING|TRUE)|NULL_KEY|TEXTURE_(?:BLANK|DEFAULT|MEDIA|PLYWOOD|TRANSPARENT)|URL_REQUEST_(?:GRANTED|DENIED))\\b"},{b:"\\b(?:ZERO_VECTOR|TOUCH_INVALID_(?:TEXCOORD|VECTOR))\\b"}]},O={cN:"built_in",b:"\\b(?:ll(?:AgentInExperience|(?:Create|DataSize|Delete|KeyCount|Keys|Read|Update)KeyValue|GetExperience(?:Details|ErrorMessage)|ReturnObjectsBy(?:ID|Owner)|Json(?:2List|[GS]etValue|ValueType)|Sin|Cos|Tan|Atan2|Sqrt|Pow|Abs|Fabs|Frand|Floor|Ceil|Round|Vec(?:Mag|Norm|Dist)|Rot(?:Between|2(?:Euler|Fwd|Left|Up))|(?:Euler|Axes)2Rot|Whisper|(?:Region|Owner)?Say|Shout|Listen(?:Control|Remove)?|Sensor(?:Repeat|Remove)?|Detected(?:Name|Key|Owner|Type|Pos|Vel|Grab|Rot|Group|LinkNumber)|Die|Ground|Wind|(?:[GS]et)(?:AnimationOverride|MemoryLimit|PrimMediaParams|ParcelMusicURL|Object(?:Desc|Name)|PhysicsMaterial|Status|Scale|Color|Alpha|Texture|Pos|Rot|Force|Torque)|ResetAnimationOverride|(?:Scale|Offset|Rotate)Texture|(?:Rot)?Target(?:Remove)?|(?:Stop)?MoveToTarget|Apply(?:Rotational)?Impulse|Set(?:KeyframedMotion|ContentType|RegionPos|(?:Angular)?Velocity|Buoyancy|HoverHeight|ForceAndTorque|TimerEvent|ScriptState|Damage|TextureAnim|Sound(?:Queueing|Radius)|Vehicle(?:Type|(?:Float|Vector|Rotation)Param)|(?:Touch|Sit)?Text|Camera(?:Eye|At)Offset|PrimitiveParams|ClickAction|Link(?:Alpha|Color|PrimitiveParams(?:Fast)?|Texture(?:Anim)?|Camera|Media)|RemoteScriptAccessPin|PayPrice|LocalRot)|ScaleByFactor|Get(?:(?:Max|Min)ScaleFactor|ClosestNavPoint|StaticPath|SimStats|Env|PrimitiveParams|Link(?:PrimitiveParams|Number(?:OfSides)?|Key|Name|Media)|HTTPHeader|FreeURLs|Object(?:Details|PermMask|PrimCount)|Parcel(?:MaxPrims|Details|Prim(?:Count|Owners))|Attached(?:List)?|(?:SPMax|Free|Used)Memory|Region(?:Name|TimeDilation|FPS|Corner|AgentCount)|Root(?:Position|Rotation)|UnixTime|(?:Parcel|Region)Flags|(?:Wall|GMT)clock|SimulatorHostname|BoundingBox|GeometricCenter|Creator|NumberOf(?:Prims|NotecardLines|Sides)|Animation(?:List)?|(?:Camera|Local)(?:Pos|Rot)|Vel|Accel|Omega|Time(?:stamp|OfDay)|(?:Object|CenterOf)?Mass|MassMKS|Energy|Owner|(?:Owner)?Key|SunDirection|Texture(?:Offset|Scale|Rot)|Inventory(?:Number|Name|Key|Type|Creator|PermMask)|Permissions(?:Key)?|StartParameter|List(?:Length|EntryType)|Date|Agent(?:Size|Info|Language|List)|LandOwnerAt|NotecardLine|Script(?:Name|State))|(?:Get|Reset|GetAndReset)Time|PlaySound(?:Slave)?|LoopSound(?:Master|Slave)?|(?:Trigger|Stop|Preload)Sound|(?:(?:Get|Delete)Sub|Insert)String|To(?:Upper|Lower)|Give(?:InventoryList|Money)|RezObject|(?:Stop)?LookAt|Sleep|CollisionFilter|(?:Take|Release)Controls|DetachFromAvatar|AttachToAvatar(?:Temp)?|InstantMessage|(?:GetNext)?Email|StopHover|MinEventDelay|RotLookAt|String(?:Length|Trim)|(?:Start|Stop)Animation|TargetOmega|Request(?:Experience)?Permissions|(?:Create|Break)Link|BreakAllLinks|(?:Give|Remove)Inventory|Water|PassTouches|Request(?:Agent|Inventory)Data|TeleportAgent(?:Home|GlobalCoords)?|ModifyLand|CollisionSound|ResetScript|MessageLinked|PushObject|PassCollisions|AxisAngle2Rot|Rot2(?:Axis|Angle)|A(?:cos|sin)|AngleBetween|AllowInventoryDrop|SubStringIndex|List2(?:CSV|Integer|Json|Float|String|Key|Vector|Rot|List(?:Strided)?)|DeleteSubList|List(?:Statistics|Sort|Randomize|(?:Insert|Find|Replace)List)|EdgeOfWorld|AdjustSoundVolume|Key2Name|TriggerSoundLimited|EjectFromLand|(?:CSV|ParseString)2List|OverMyLand|SameGroup|UnSit|Ground(?:Slope|Normal|Contour)|GroundRepel|(?:Set|Remove)VehicleFlags|(?:AvatarOn)?(?:Link)?SitTarget|Script(?:Danger|Profiler)|Dialog|VolumeDetect|ResetOtherScript|RemoteLoadScriptPin|(?:Open|Close)RemoteDataChannel|SendRemoteData|RemoteDataReply|(?:Integer|String)ToBase64|XorBase64|Log(?:10)?|Base64To(?:String|Integer)|ParseStringKeepNulls|RezAtRoot|RequestSimulatorData|ForceMouselook|(?:Load|Release|(?:E|Une)scape)URL|ParcelMedia(?:CommandList|Query)|ModPow|MapDestination|(?:RemoveFrom|AddTo|Reset)Land(?:Pass|Ban)List|(?:Set|Clear)CameraParams|HTTP(?:Request|Response)|TextBox|DetectedTouch(?:UV|Face|Pos|(?:N|Bin)ormal|ST)|(?:MD5|SHA1|DumpList2)String|Request(?:Secure)?URL|Clear(?:Prim|Link)Media|(?:Link)?ParticleSystem|(?:Get|Request)(?:Username|DisplayName)|RegionSayTo|CastRay|GenerateKey|TransferLindenDollars|ManageEstateAccess|(?:Create|Delete)Character|ExecCharacterCmd|Evade|FleeFrom|NavigateTo|PatrolPoints|Pursue|UpdateCharacter|WanderWithin))\\b"};return{i:":",c:[e,{cN:"comment",v:[E.C("//","$"),E.C("/\\*","\\*/")]},A,{cN:"section",v:[{b:"\\b(?:state|default)\\b"},{b:"\\b(?:state_(?:entry|exit)|touch(?:_(?:start|end))?|(?:land_)?collision(?:_(?:start|end))?|timer|listen|(?:no_)?sensor|control|(?:not_)?at_(?:rot_)?target|money|email|experience_permissions(?:_denied)?|run_time_permissions|changed|attach|dataserver|moving_(?:start|end)|link_message|(?:on|object)_rez|remote_data|http_re(?:sponse|quest)|path_update|transaction_result)\\b"}]},O,R,{cN:"type",b:"\\b(?:integer|float|string|key|vector|quaternion|rotation|list)\\b"}]}});hljs.registerLanguage("tp",function(O){var R={cN:"number",b:"[1-9][0-9]*",r:0},E={cN:"symbol",b:":[^\\]]+"},T={cN:"built_in",b:"(AR|P|PAYLOAD|PR|R|SR|RSR|LBL|VR|UALM|MESSAGE|UTOOL|UFRAME|TIMER| TIMER_OVERFLOW|JOINT_MAX_SPEED|RESUME_PROG|DIAG_REC)\\[",e:"\\]",c:["self",R,E]},N={cN:"built_in",b:"(AI|AO|DI|DO|F|RI|RO|UI|UO|GI|GO|SI|SO)\\[",e:"\\]",c:["self",R,O.QSM,E]};return{k:{keyword:"ABORT ACC ADJUST AND AP_LD BREAK CALL CNT COL CONDITION CONFIG DA DB DIV DETECT ELSE END ENDFOR ERR_NUM ERROR_PROG FINE FOR GP GUARD INC IF JMP LINEAR_MAX_SPEED LOCK MOD MONITOR OFFSET Offset OR OVERRIDE PAUSE PREG PTH RT_LD RUN SELECT SKIP Skip TA TB TO TOOL_OFFSET Tool_Offset UF UT UFRAME_NUM UTOOL_NUM UNLOCK WAIT X Y Z W P R STRLEN SUBSTR FINDSTR VOFFSET PROG ATTR MN POS",literal:"ON OFF max_speed LPOS JPOS ENABLE DISABLE START STOP RESET"},c:[T,N,{cN:"keyword",b:"/(PROG|ATTR|MN|POS|END)\\b"},{cN:"keyword",b:"(CALL|RUN|POINT_LOGIC|LBL)\\b"},{cN:"keyword",b:"\\b(ACC|CNT|Skip|Offset|PSPD|RT_LD|AP_LD|Tool_Offset)"},{cN:"number",b:"\\d+(sec|msec|mm/sec|cm/min|inch/min|deg/sec|mm|in|cm)?\\b",r:0},O.C("//","[;$]"),O.C("!","[;$]"),O.C("--eg:","$"),O.QSM,{cN:"string",b:"'",e:"'"},O.CNM,{cN:"variable",b:"\\$[A-Za-z0-9_]+"}]}});hljs.registerLanguage("moonscript",function(e){var t={keyword:"if then not for in while do return else elseif break continue switch and or unless when class extends super local import export from using",literal:"true false nil",built_in:"_G _VERSION assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall coroutine debug io math os package string table"},r="[A-Za-z$_][0-9A-Za-z$_]*",s={cN:"subst",b:/#\{/,e:/}/,k:t},a=[e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'/,e:/'/,c:[e.BE]},{b:/"/,e:/"/,c:[e.BE,s]}]},{cN:"built_in",b:"@__"+e.IR},{b:"@"+e.IR},{b:e.IR+"\\\\"+e.IR}];s.c=a;var c=e.inherit(e.TM,{b:r}),n="(\\(.*\\))?\\s*\\B[-=]>",i={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:t,c:["self"].concat(a)}]};return{aliases:["moon"],k:t,i:/\/\*/,c:a.concat([e.C("--","$"),{cN:"function",b:"^\\s*"+r+"\\s*=\\s*"+n,e:"[-=]>",rB:!0,c:[c,i]},{b:/[\(,:=]\s*/,r:0,c:[{cN:"function",b:n,e:"[-=]>",rB:!0,c:[i]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[c]},c]},{cN:"name",b:r+":",e:":",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage("routeros",function(e){var r="foreach do while for if from to step else on-error and or not in",i="global local beep delay put len typeof pick log time set find environment terminal error execute parse resolve toarray tobool toid toip toip6 tonum tostr totime",o="add remove enable disable set get print export edit find run debug error info warning",t="true false yes no nothing nil null",s="traffic-flow traffic-generator firewall scheduler aaa accounting address-list address align area bandwidth-server bfd bgp bridge client clock community config connection console customer default dhcp-client dhcp-server discovery dns e-mail ethernet filter firewall firmware gps graphing group hardware health hotspot identity igmp-proxy incoming instance interface ip ipsec ipv6 irq l2tp-server lcd ldp logging mac-server mac-winbox mangle manual mirror mme mpls nat nd neighbor network note ntp ospf ospf-v3 ovpn-server page peer pim ping policy pool port ppp pppoe-client pptp-server prefix profile proposal proxy queue radius resource rip ripng route routing screen script security-profiles server service service-port settings shares smb sms sniffer snmp snooper socks sstp-server system tool tracking type upgrade upnp user-manager users user vlan secret vrrp watchdog web-access wireless pptp pppoe lan wan layer7-protocol lease simple raw",n={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},p={cN:"string",b:/"/,e:/"/,c:[e.BE,n,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["routeros","mikrotik"],cI:!0,l:/:?[\w-]+/,k:{literal:t,keyword:r+" :"+r.split(" ").join(" :")+" :"+i.split(" ").join(" :")},c:[{v:[{b:/^@/,e:/$/},{b:/\/\*/,e:/\*\//},{b:/%%/,e:/$/},{b:/^'/,e:/$/},{b:/^\s*\/[\w-]+=/,e:/$/},{b:/\/\//,e:/$/},{b:/^\[\\]$/},{b:/<\//,e:/>/},{b:/^facet /,e:/\}/},{b:"^1\\.\\.(\\d+)$",e:/$/}],i:/./},e.C("^#","$"),p,a,n,{b:/[\w-]+\=([^\s\{\}\[\]\(\)]+)/,r:0,rB:!0,c:[{cN:"attribute",b:/[^=]+/},{b:/=/,eW:!0,r:0,c:[p,a,n,{cN:"literal",b:"\\b("+t.split(" ").join("|")+")\\b"},{b:/("[^"]*"|[^\s\{\}\[\]]+)/}]}]},{cN:"number",b:/\*[0-9a-fA-F]+/},{b:"\\b("+o.split(" ").join("|")+")([\\s[(]|])",rB:!0,c:[{cN:"builtin-name",b:/\w+/}]},{cN:"built_in",v:[{b:"(\\.\\./|/|\\s)(("+s.split(" ").join("|")+");?\\s)+",r:10},{b:/\.\./}]}]}});hljs.registerLanguage("protobuf",function(e){return{k:{keyword:"package import option optional required repeated group",built_in:"double float int32 int64 uint32 uint64 sint32 sint64 fixed32 fixed64 sfixed32 sfixed64 bool string bytes",literal:"true false"},c:[e.QSM,e.NM,e.CLCM,{cN:"class",bK:"message enum service",e:/\{/,i:/\n/,c:[e.inherit(e.TM,{starts:{eW:!0,eE:!0}})]},{cN:"function",bK:"rpc",e:/;/,eE:!0,k:"rpc returns"},{b:/^\s*[A-Z_]+/,e:/\s*=/,eE:!0}]}});hljs.registerLanguage("vim",function(e){return{l:/[!#@\w]+/,k:{keyword:"N|0 P|0 X|0 a|0 ab abc abo al am an|0 ar arga argd arge argdo argg argl argu as au aug aun b|0 bN ba bad bd be bel bf bl bm bn bo bp br brea breaka breakd breakl bro bufdo buffers bun bw c|0 cN cNf ca cabc caddb cad caddf cal cat cb cc ccl cd ce cex cf cfir cgetb cgete cg changes chd che checkt cl cla clo cm cmapc cme cn cnew cnf cno cnorea cnoreme co col colo com comc comp con conf cope cp cpf cq cr cs cst cu cuna cunme cw delm deb debugg delc delf dif diffg diffo diffp diffpu diffs diffthis dig di dl dell dj dli do doautoa dp dr ds dsp e|0 ea ec echoe echoh echom echon el elsei em en endfo endf endt endw ene ex exe exi exu f|0 files filet fin fina fini fir fix fo foldc foldd folddoc foldo for fu go gr grepa gu gv ha helpf helpg helpt hi hid his ia iabc if ij il im imapc ime ino inorea inoreme int is isp iu iuna iunme j|0 ju k|0 keepa kee keepj lN lNf l|0 lad laddb laddf la lan lat lb lc lch lcl lcs le lefta let lex lf lfir lgetb lgete lg lgr lgrepa lh ll lla lli lmak lm lmapc lne lnew lnf ln loadk lo loc lockv lol lope lp lpf lr ls lt lu lua luad luaf lv lvimgrepa lw m|0 ma mak map mapc marks mat me menut mes mk mks mksp mkv mkvie mod mz mzf nbc nb nbs new nm nmapc nme nn nnoreme noa no noh norea noreme norm nu nun nunme ol o|0 om omapc ome on ono onoreme opt ou ounme ow p|0 profd prof pro promptr pc ped pe perld po popu pp pre prev ps pt ptN ptf ptj ptl ptn ptp ptr pts pu pw py3 python3 py3d py3f py pyd pyf quita qa rec red redi redr redraws reg res ret retu rew ri rightb rub rubyd rubyf rund ru rv sN san sa sal sav sb sbN sba sbf sbl sbm sbn sbp sbr scrip scripte scs se setf setg setl sf sfir sh sim sig sil sl sla sm smap smapc sme sn sni sno snor snoreme sor so spelld spe spelli spellr spellu spellw sp spr sre st sta startg startr star stopi stj sts sun sunm sunme sus sv sw sy synti sync tN tabN tabc tabdo tabe tabf tabfir tabl tabm tabnew tabn tabo tabp tabr tabs tab ta tags tc tcld tclf te tf th tj tl tm tn to tp tr try ts tu u|0 undoj undol una unh unl unlo unm unme uns up ve verb vert vim vimgrepa vi viu vie vm vmapc vme vne vn vnoreme vs vu vunme windo w|0 wN wa wh wi winc winp wn wp wq wqa ws wu wv x|0 xa xmapc xm xme xn xnoreme xu xunme y|0 z|0 ~ Next Print append abbreviate abclear aboveleft all amenu anoremenu args argadd argdelete argedit argglobal arglocal argument ascii autocmd augroup aunmenu buffer bNext ball badd bdelete behave belowright bfirst blast bmodified bnext botright bprevious brewind break breakadd breakdel breaklist browse bunload bwipeout change cNext cNfile cabbrev cabclear caddbuffer caddexpr caddfile call catch cbuffer cclose center cexpr cfile cfirst cgetbuffer cgetexpr cgetfile chdir checkpath checktime clist clast close cmap cmapclear cmenu cnext cnewer cnfile cnoremap cnoreabbrev cnoremenu copy colder colorscheme command comclear compiler continue confirm copen cprevious cpfile cquit crewind cscope cstag cunmap cunabbrev cunmenu cwindow delete delmarks debug debuggreedy delcommand delfunction diffupdate diffget diffoff diffpatch diffput diffsplit digraphs display deletel djump dlist doautocmd doautoall deletep drop dsearch dsplit edit earlier echo echoerr echohl echomsg else elseif emenu endif endfor endfunction endtry endwhile enew execute exit exusage file filetype find finally finish first fixdel fold foldclose folddoopen folddoclosed foldopen function global goto grep grepadd gui gvim hardcopy help helpfind helpgrep helptags highlight hide history insert iabbrev iabclear ijump ilist imap imapclear imenu inoremap inoreabbrev inoremenu intro isearch isplit iunmap iunabbrev iunmenu join jumps keepalt keepmarks keepjumps lNext lNfile list laddexpr laddbuffer laddfile last language later lbuffer lcd lchdir lclose lcscope left leftabove lexpr lfile lfirst lgetbuffer lgetexpr lgetfile lgrep lgrepadd lhelpgrep llast llist lmake lmap lmapclear lnext lnewer lnfile lnoremap loadkeymap loadview lockmarks lockvar lolder lopen lprevious lpfile lrewind ltag lunmap luado luafile lvimgrep lvimgrepadd lwindow move mark make mapclear match menu menutranslate messages mkexrc mksession mkspell mkvimrc mkview mode mzscheme mzfile nbclose nbkey nbsart next nmap nmapclear nmenu nnoremap nnoremenu noautocmd noremap nohlsearch noreabbrev noremenu normal number nunmap nunmenu oldfiles open omap omapclear omenu only onoremap onoremenu options ounmap ounmenu ownsyntax print profdel profile promptfind promptrepl pclose pedit perl perldo pop popup ppop preserve previous psearch ptag ptNext ptfirst ptjump ptlast ptnext ptprevious ptrewind ptselect put pwd py3do py3file python pydo pyfile quit quitall qall read recover redo redir redraw redrawstatus registers resize retab return rewind right rightbelow ruby rubydo rubyfile rundo runtime rviminfo substitute sNext sandbox sargument sall saveas sbuffer sbNext sball sbfirst sblast sbmodified sbnext sbprevious sbrewind scriptnames scriptencoding scscope set setfiletype setglobal setlocal sfind sfirst shell simalt sign silent sleep slast smagic smapclear smenu snext sniff snomagic snoremap snoremenu sort source spelldump spellgood spellinfo spellrepall spellundo spellwrong split sprevious srewind stop stag startgreplace startreplace startinsert stopinsert stjump stselect sunhide sunmap sunmenu suspend sview swapname syntax syntime syncbind tNext tabNext tabclose tabedit tabfind tabfirst tablast tabmove tabnext tabonly tabprevious tabrewind tag tcl tcldo tclfile tearoff tfirst throw tjump tlast tmenu tnext topleft tprevious trewind tselect tunmenu undo undojoin undolist unabbreviate unhide unlet unlockvar unmap unmenu unsilent update vglobal version verbose vertical vimgrep vimgrepadd visual viusage view vmap vmapclear vmenu vnew vnoremap vnoremenu vsplit vunmap vunmenu write wNext wall while winsize wincmd winpos wnext wprevious wqall wsverb wundo wviminfo xit xall xmapclear xmap xmenu xnoremap xnoremenu xunmap xunmenu yank",built_in:"synIDtrans atan2 range matcharg did_filetype asin feedkeys xor argv complete_check add getwinposx getqflist getwinposy screencol clearmatches empty extend getcmdpos mzeval garbagecollect setreg ceil sqrt diff_hlID inputsecret get getfperm getpid filewritable shiftwidth max sinh isdirectory synID system inputrestore winline atan visualmode inputlist tabpagewinnr round getregtype mapcheck hasmapto histdel argidx findfile sha256 exists toupper getcmdline taglist string getmatches bufnr strftime winwidth bufexists strtrans tabpagebuflist setcmdpos remote_read printf setloclist getpos getline bufwinnr float2nr len getcmdtype diff_filler luaeval resolve libcallnr foldclosedend reverse filter has_key bufname str2float strlen setline getcharmod setbufvar index searchpos shellescape undofile foldclosed setqflist buflisted strchars str2nr virtcol floor remove undotree remote_expr winheight gettabwinvar reltime cursor tabpagenr finddir localtime acos getloclist search tanh matchend rename gettabvar strdisplaywidth type abs py3eval setwinvar tolower wildmenumode log10 spellsuggest bufloaded synconcealed nextnonblank server2client complete settabwinvar executable input wincol setmatches getftype hlID inputsave searchpair or screenrow line settabvar histadd deepcopy strpart remote_peek and eval getftime submatch screenchar winsaveview matchadd mkdir screenattr getfontname libcall reltimestr getfsize winnr invert pow getbufline byte2line soundfold repeat fnameescape tagfiles sin strwidth spellbadword trunc maparg log lispindent hostname setpos globpath remote_foreground getchar synIDattr fnamemodify cscope_connection stridx winbufnr indent min complete_add nr2char searchpairpos inputdialog values matchlist items hlexists strridx browsedir expand fmod pathshorten line2byte argc count getwinvar glob foldtextresult getreg foreground cosh matchdelete has char2nr simplify histget searchdecl iconv winrestcmd pumvisible writefile foldlevel haslocaldir keys cos matchstr foldtext histnr tan tempname getcwd byteidx getbufvar islocked escape eventhandler remote_send serverlist winrestview synstack pyeval prevnonblank readfile cindent filereadable changenr exp"},i:/;/,c:[e.NM,e.ASM,{cN:"string",b:/"(\\"|\n\\|[^"\n])*"/},e.C('"',"$"),{cN:"variable",b:/[bwtglsav]:[\w\d_]*/},{cN:"function",bK:"function function!",e:"$",r:0,c:[e.TM,{cN:"params",b:"\\(",e:"\\)"}]},{cN:"symbol",b:/<[\w-]+>/}]}});hljs.registerLanguage("zephir",function(e){var i={cN:"string",c:[e.BE],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},n={v:[e.BNM,e.CNM]};return{aliases:["zep"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var let while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally int uint long ulong char uchar double float bool boolean stringlikely unlikely",c:[e.CLCM,e.HCM,e.C("/\\*","\\*/",{c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.C("__halt_compiler.+?;",!1,{eW:!0,k:"__halt_compiler",l:e.UIR}),{cN:"string",b:"<<<['\"]?\\w+['\"]?$",e:"^\\w+;",c:[e.BE]},{b:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",e.CBCM,i,n]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},i,n]}});hljs.registerLanguage("php",function(e){var c={b:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},i={cN:"meta",b:/<\?(php)?|\?>/},t={cN:"string",c:[e.BE,i],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},a={v:[e.BNM,e.CNM]};return{aliases:["php3","php4","php5","php6"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[e.HCM,e.C("//","$",{c:[i]}),e.C("/\\*","\\*/",{c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.C("__halt_compiler.+?;",!1,{eW:!0,k:"__halt_compiler",l:e.UIR}),{cN:"string",b:/<<<['"]?\w+['"]?$/,e:/^\w+;?$/,c:[e.BE,{cN:"subst",v:[{b:/\$\w+/},{b:/\{\$/,e:/\}/}]}]},i,{cN:"keyword",b:/\$this\b/},c,{b:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",c,e.CBCM,t,a]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},t,a]}});hljs.registerLanguage("asciidoc",function(e){return{aliases:["adoc"],c:[e.C("^/{4,}\\n","\\n/{4,}$",{r:10}),e.C("^//","$",{r:0}),{cN:"title",b:"^\\.\\w.*$"},{b:"^[=\\*]{4,}\\n",e:"\\n^[=\\*]{4,}$",r:10},{cN:"section",r:10,v:[{b:"^(={1,5}) .+?( \\1)?$"},{b:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$"}]},{cN:"meta",b:"^:.+?:",e:"\\s",eE:!0,r:10},{cN:"meta",b:"^\\[.+?\\]$",r:0},{cN:"quote",b:"^_{4,}\\n",e:"\\n_{4,}$",r:10},{cN:"code",b:"^[\\-\\.]{4,}\\n",e:"\\n[\\-\\.]{4,}$",r:10},{b:"^\\+{4,}\\n",e:"\\n\\+{4,}$",c:[{b:"<",e:">",sL:"xml",r:0}],r:10},{cN:"bullet",b:"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{cN:"symbol",b:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",r:10},{cN:"strong",b:"\\B\\*(?![\\*\\s])",e:"(\\n{2}|\\*)",c:[{b:"\\\\*\\w",r:0}]},{cN:"emphasis",b:"\\B'(?!['\\s])",e:"(\\n{2}|')",c:[{b:"\\\\'\\w",r:0}],r:0},{cN:"emphasis",b:"_(?![_\\s])",e:"(\\n{2}|_)",r:0},{cN:"string",v:[{b:"``.+?''"},{b:"`.+?'"}]},{cN:"code",b:"(`.+?`|\\+.+?\\+)",r:0},{cN:"code",b:"^[ \\t]",e:"$",r:0},{b:"^'{3,}[ \\t]*$",r:10},{b:"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]",rB:!0,c:[{b:"(link|image:?):",r:0},{cN:"link",b:"\\w",e:"[^\\[]+",r:0},{cN:"string",b:"\\[",e:"\\]",eB:!0,eE:!0,r:0}],r:10}]}});hljs.registerLanguage("yaml",function(e){var b="true false yes no null",a="^[ \\-]*",r="[a-zA-Z_][\\w\\-]*",t={cN:"attr",v:[{b:a+r+":"},{b:a+'"'+r+'":'},{b:a+"'"+r+"':"}]},c={cN:"template-variable",v:[{b:"{{",e:"}}"},{b:"%{",e:"}"}]},l={cN:"string",r:0,v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/\S+/}],c:[e.BE,c]};return{cI:!0,aliases:["yml","YAML","yaml"],c:[t,{cN:"meta",b:"^---s*$",r:10},{cN:"string",b:"[\\|>] *$",rE:!0,c:l.c,e:t.v[0].b},{b:"<%[%=-]?",e:"[%-]?%>",sL:"ruby",eB:!0,eE:!0,r:0},{cN:"type",b:"!!"+e.UIR},{cN:"meta",b:"&"+e.UIR+"$"},{cN:"meta",b:"\\*"+e.UIR+"$"},{cN:"bullet",b:"^ *-",r:0},e.HCM,{bK:b,k:{literal:b}},e.CNM,l]}});hljs.registerLanguage("profile",function(e){return{c:[e.CNM,{b:"[a-zA-Z_][\\da-zA-Z_]+\\.[\\da-zA-Z_]{1,3}",e:":",eE:!0},{b:"(ncalls|tottime|cumtime)",e:"$",k:"ncalls tottime|10 cumtime|10 filename",r:10},{b:"function calls",e:"$",c:[e.CNM],r:10},e.ASM,e.QSM,{cN:"string",b:"\\(",e:"\\)$",eB:!0,eE:!0,r:0}]}});hljs.registerLanguage("autoit",function(e){var t="ByRef Case Const ContinueCase ContinueLoop Default Dim Do Else ElseIf EndFunc EndIf EndSelect EndSwitch EndWith Enum Exit ExitLoop For Func Global If In Local Next ReDim Return Select Static Step Switch Then To Until Volatile WEnd While With",r="True False And Null Not Or",i="Abs ACos AdlibRegister AdlibUnRegister Asc AscW ASin Assign ATan AutoItSetOption AutoItWinGetTitle AutoItWinSetTitle Beep Binary BinaryLen BinaryMid BinaryToString BitAND BitNOT BitOR BitRotate BitShift BitXOR BlockInput Break Call CDTray Ceiling Chr ChrW ClipGet ClipPut ConsoleRead ConsoleWrite ConsoleWriteError ControlClick ControlCommand ControlDisable ControlEnable ControlFocus ControlGetFocus ControlGetHandle ControlGetPos ControlGetText ControlHide ControlListView ControlMove ControlSend ControlSetText ControlShow ControlTreeView Cos Dec DirCopy DirCreate DirGetSize DirMove DirRemove DllCall DllCallAddress DllCallbackFree DllCallbackGetPtr DllCallbackRegister DllClose DllOpen DllStructCreate DllStructGetData DllStructGetPtr DllStructGetSize DllStructSetData DriveGetDrive DriveGetFileSystem DriveGetLabel DriveGetSerial DriveGetType DriveMapAdd DriveMapDel DriveMapGet DriveSetLabel DriveSpaceFree DriveSpaceTotal DriveStatus EnvGet EnvSet EnvUpdate Eval Execute Exp FileChangeDir FileClose FileCopy FileCreateNTFSLink FileCreateShortcut FileDelete FileExists FileFindFirstFile FileFindNextFile FileFlush FileGetAttrib FileGetEncoding FileGetLongName FileGetPos FileGetShortcut FileGetShortName FileGetSize FileGetTime FileGetVersion FileInstall FileMove FileOpen FileOpenDialog FileRead FileReadLine FileReadToArray FileRecycle FileRecycleEmpty FileSaveDialog FileSelectFolder FileSetAttrib FileSetEnd FileSetPos FileSetTime FileWrite FileWriteLine Floor FtpSetProxy FuncName GUICreate GUICtrlCreateAvi GUICtrlCreateButton GUICtrlCreateCheckbox GUICtrlCreateCombo GUICtrlCreateContextMenu GUICtrlCreateDate GUICtrlCreateDummy GUICtrlCreateEdit GUICtrlCreateGraphic GUICtrlCreateGroup GUICtrlCreateIcon GUICtrlCreateInput GUICtrlCreateLabel GUICtrlCreateList GUICtrlCreateListView GUICtrlCreateListViewItem GUICtrlCreateMenu GUICtrlCreateMenuItem GUICtrlCreateMonthCal GUICtrlCreateObj GUICtrlCreatePic GUICtrlCreateProgress GUICtrlCreateRadio GUICtrlCreateSlider GUICtrlCreateTab GUICtrlCreateTabItem GUICtrlCreateTreeView GUICtrlCreateTreeViewItem GUICtrlCreateUpdown GUICtrlDelete GUICtrlGetHandle GUICtrlGetState GUICtrlRead GUICtrlRecvMsg GUICtrlRegisterListViewSort GUICtrlSendMsg GUICtrlSendToDummy GUICtrlSetBkColor GUICtrlSetColor GUICtrlSetCursor GUICtrlSetData GUICtrlSetDefBkColor GUICtrlSetDefColor GUICtrlSetFont GUICtrlSetGraphic GUICtrlSetImage GUICtrlSetLimit GUICtrlSetOnEvent GUICtrlSetPos GUICtrlSetResizing GUICtrlSetState GUICtrlSetStyle GUICtrlSetTip GUIDelete GUIGetCursorInfo GUIGetMsg GUIGetStyle GUIRegisterMsg GUISetAccelerators GUISetBkColor GUISetCoord GUISetCursor GUISetFont GUISetHelp GUISetIcon GUISetOnEvent GUISetState GUISetStyle GUIStartGroup GUISwitch Hex HotKeySet HttpSetProxy HttpSetUserAgent HWnd InetClose InetGet InetGetInfo InetGetSize InetRead IniDelete IniRead IniReadSection IniReadSectionNames IniRenameSection IniWrite IniWriteSection InputBox Int IsAdmin IsArray IsBinary IsBool IsDeclared IsDllStruct IsFloat IsFunc IsHWnd IsInt IsKeyword IsNumber IsObj IsPtr IsString Log MemGetStats Mod MouseClick MouseClickDrag MouseDown MouseGetCursor MouseGetPos MouseMove MouseUp MouseWheel MsgBox Number ObjCreate ObjCreateInterface ObjEvent ObjGet ObjName OnAutoItExitRegister OnAutoItExitUnRegister Ping PixelChecksum PixelGetColor PixelSearch ProcessClose ProcessExists ProcessGetStats ProcessList ProcessSetPriority ProcessWait ProcessWaitClose ProgressOff ProgressOn ProgressSet Ptr Random RegDelete RegEnumKey RegEnumVal RegRead RegWrite Round Run RunAs RunAsWait RunWait Send SendKeepActive SetError SetExtended ShellExecute ShellExecuteWait Shutdown Sin Sleep SoundPlay SoundSetWaveVolume SplashImageOn SplashOff SplashTextOn Sqrt SRandom StatusbarGetText StderrRead StdinWrite StdioClose StdoutRead String StringAddCR StringCompare StringFormat StringFromASCIIArray StringInStr StringIsAlNum StringIsAlpha StringIsASCII StringIsDigit StringIsFloat StringIsInt StringIsLower StringIsSpace StringIsUpper StringIsXDigit StringLeft StringLen StringLower StringMid StringRegExp StringRegExpReplace StringReplace StringReverse StringRight StringSplit StringStripCR StringStripWS StringToASCIIArray StringToBinary StringTrimLeft StringTrimRight StringUpper Tan TCPAccept TCPCloseSocket TCPConnect TCPListen TCPNameToIP TCPRecv TCPSend TCPShutdown, UDPShutdown TCPStartup, UDPStartup TimerDiff TimerInit ToolTip TrayCreateItem TrayCreateMenu TrayGetMsg TrayItemDelete TrayItemGetHandle TrayItemGetState TrayItemGetText TrayItemSetOnEvent TrayItemSetState TrayItemSetText TraySetClick TraySetIcon TraySetOnEvent TraySetPauseIcon TraySetState TraySetToolTip TrayTip UBound UDPBind UDPCloseSocket UDPOpen UDPRecv UDPSend VarGetType WinActivate WinActive WinClose WinExists WinFlash WinGetCaretPos WinGetClassList WinGetClientSize WinGetHandle WinGetPos WinGetProcess WinGetState WinGetText WinGetTitle WinKill WinList WinMenuSelectItem WinMinimizeAll WinMinimizeAllUndo WinMove WinSetOnTop WinSetState WinSetTitle WinSetTrans WinWait",l={v:[e.C(";","$",{r:0}),e.C("#cs","#ce"),e.C("#comments-start","#comments-end")]},n={b:"\\$[A-z0-9_]+"},o={cN:"string",v:[{b:/"/,e:/"/,c:[{b:/""/,r:0}]},{b:/'/,e:/'/,c:[{b:/''/,r:0}]}]},a={v:[e.BNM,e.CNM]},S={cN:"meta",b:"#",e:"$",k:{"meta-keyword":"comments include include-once NoTrayIcon OnAutoItStartRegister pragma compile RequireAdmin"},c:[{b:/\\\n/,r:0},{bK:"include",k:{"meta-keyword":"include"},e:"$",c:[o,{cN:"meta-string",v:[{b:"<",e:">"},{b:/"/,e:/"/,c:[{b:/""/,r:0}]},{b:/'/,e:/'/,c:[{b:/''/,r:0}]}]}]},o,l]},C={cN:"symbol",b:"@[A-z0-9_]+"},s={cN:"function",bK:"Func",e:"$",i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:[n,o,a]}]};return{cI:!0,i:/\/\*/,k:{keyword:t,built_in:i,literal:r},c:[l,n,o,a,S,C,s]}});hljs.registerLanguage("mipsasm",function(s){return{cI:!0,aliases:["mips"],l:"\\.?"+s.IR,k:{meta:".2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .ltorg ",built_in:"$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 $17 $18 $19 $20 $21 $22 $23 $24 $25 $26 $27 $28 $29 $30 $31 zero at v0 v1 a0 a1 a2 a3 a4 a5 a6 a7 t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 s0 s1 s2 s3 s4 s5 s6 s7 s8 k0 k1 gp sp fp ra $f0 $f1 $f2 $f2 $f4 $f5 $f6 $f7 $f8 $f9 $f10 $f11 $f12 $f13 $f14 $f15 $f16 $f17 $f18 $f19 $f20 $f21 $f22 $f23 $f24 $f25 $f26 $f27 $f28 $f29 $f30 $f31 Context Random EntryLo0 EntryLo1 Context PageMask Wired EntryHi HWREna BadVAddr Count Compare SR IntCtl SRSCtl SRSMap Cause EPC PRId EBase Config Config1 Config2 Config3 LLAddr Debug DEPC DESAVE CacheErr ECC ErrorEPC TagLo DataLo TagHi DataHi WatchLo WatchHi PerfCtl PerfCnt "},c:[{cN:"keyword",b:"\\b(addi?u?|andi?|b(al)?|beql?|bgez(al)?l?|bgtzl?|blezl?|bltz(al)?l?|bnel?|cl[oz]|divu?|ext|ins|j(al)?|jalr(.hb)?|jr(.hb)?|lbu?|lhu?|ll|lui|lw[lr]?|maddu?|mfhi|mflo|movn|movz|move|msubu?|mthi|mtlo|mul|multu?|nop|nor|ori?|rotrv?|sb|sc|se[bh]|sh|sllv?|slti?u?|srav?|srlv?|subu?|sw[lr]?|xori?|wsbh|abs.[sd]|add.[sd]|alnv.ps|bc1[ft]l?|c.(s?f|un|u?eq|[ou]lt|[ou]le|ngle?|seq|l[et]|ng[et]).[sd]|(ceil|floor|round|trunc).[lw].[sd]|cfc1|cvt.d.[lsw]|cvt.l.[dsw]|cvt.ps.s|cvt.s.[dlw]|cvt.s.p[lu]|cvt.w.[dls]|div.[ds]|ldx?c1|luxc1|lwx?c1|madd.[sd]|mfc1|mov[fntz]?.[ds]|msub.[sd]|mth?c1|mul.[ds]|neg.[ds]|nmadd.[ds]|nmsub.[ds]|p[lu][lu].ps|recip.fmt|r?sqrt.[ds]|sdx?c1|sub.[ds]|suxc1|swx?c1|break|cache|d?eret|[de]i|ehb|mfc0|mtc0|pause|prefx?|rdhwr|rdpgpr|sdbbp|ssnop|synci?|syscall|teqi?|tgei?u?|tlb(p|r|w[ir])|tlti?u?|tnei?|wait|wrpgpr)",e:"\\s"},s.C("[;#]","$"),s.CBCM,s.QSM,{cN:"string",b:"'",e:"[^\\\\]'",r:0},{cN:"title",b:"\\|",e:"\\|",i:"\\n",r:0},{cN:"number",v:[{b:"0x[0-9a-f]+"},{b:"\\b-?\\d+"}],r:0},{cN:"symbol",v:[{b:"^\\s*[a-z_\\.\\$][a-z0-9_\\.\\$]+:"},{b:"^\\s*[0-9]+:"},{b:"[0-9]+[bf]"}],r:0}],i:"/"}});hljs.registerLanguage("typescript",function(e){var r={keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class public private protected get set super static implements enum export import declare type namespace abstract as from extends async await",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document any number boolean string void Promise"};return{aliases:["ts"],k:r,c:[{cN:"meta",b:/^\s*['"]use strict['"]/},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+e.IR+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:e.IR},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:["self",e.CLCM,e.CBCM]}]}]}],r:0},{cN:"function",b:"function",e:/[\{;]/,eE:!0,k:r,c:["self",e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:[e.CLCM,e.CBCM],i:/["'\(]/}],i:/%/,r:0},{bK:"constructor",e:/\{/,eE:!0,c:["self",{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:[e.CLCM,e.CBCM],i:/["'\(]/}]},{b:/module\./,k:{built_in:"module"},r:0},{bK:"module",e:/\{/,eE:!0},{bK:"interface",e:/\{/,eE:!0,k:"interface extends"},{b:/\$[(.]/},{b:"\\."+e.IR,r:0},{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("crystal",function(e){function b(e,b){var r=[{b:e,e:b}];return r[0].c=r,r}var r="(_[uif](8|16|32|64))?",c="[a-zA-Z_]\\w*[!?=]?",i="!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",n="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\][=?]?",s={keyword:"abstract alias as as? asm begin break case class def do else elsif end ensure enum extend for fun if include instance_sizeof is_a? lib macro module next nil? of out pointerof private protected rescue responds_to? return require select self sizeof struct super then type typeof union uninitialized unless until when while with yield __DIR__ __END_LINE__ __FILE__ __LINE__",literal:"false nil true"},t={cN:"subst",b:"#{",e:"}",k:s},a={cN:"template-variable",v:[{b:"\\{\\{",e:"\\}\\}"},{b:"\\{%",e:"%\\}"}],k:s},l={cN:"string",c:[e.BE,t],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%w?\\(",e:"\\)",c:b("\\(","\\)")},{b:"%w?\\[",e:"\\]",c:b("\\[","\\]")},{b:"%w?{",e:"}",c:b("{","}")},{b:"%w?<",e:">",c:b("<",">")},{b:"%w?/",e:"/"},{b:"%w?%",e:"%"},{b:"%w?-",e:"-"},{b:"%w?\\|",e:"\\|"},{b:/<<-\w+$/,e:/^\s*\w+$/}],r:0},u={cN:"string",v:[{b:"%q\\(",e:"\\)",c:b("\\(","\\)")},{b:"%q\\[",e:"\\]",c:b("\\[","\\]")},{b:"%q{",e:"}",c:b("{","}")},{b:"%q<",e:">",c:b("<",">")},{b:"%q/",e:"/"},{b:"%q%",e:"%"},{b:"%q-",e:"-"},{b:"%q\\|",e:"\\|"},{b:/<<-'\w+'$/,e:/^\s*\w+$/}],r:0},_={b:"("+i+")\\s*",c:[{cN:"regexp",c:[e.BE,t],v:[{b:"//[a-z]*",r:0},{b:"/",e:"/[a-z]*"},{b:"%r\\(",e:"\\)",c:b("\\(","\\)")},{b:"%r\\[",e:"\\]",c:b("\\[","\\]")},{b:"%r{",e:"}",c:b("{","}")},{b:"%r<",e:">",c:b("<",">")},{b:"%r/",e:"/"},{b:"%r%",e:"%"},{b:"%r-",e:"-"},{b:"%r\\|",e:"\\|"}]}],r:0},o={cN:"regexp",c:[e.BE,t],v:[{b:"%r\\(",e:"\\)",c:b("\\(","\\)")},{b:"%r\\[",e:"\\]",c:b("\\[","\\]")},{b:"%r{",e:"}",c:b("{","}")},{b:"%r<",e:">",c:b("<",">")},{b:"%r/",e:"/"},{b:"%r%",e:"%"},{b:"%r-",e:"-"},{b:"%r\\|",e:"\\|"}],r:0},w={cN:"meta",b:"@\\[",e:"\\]",c:[e.inherit(e.QSM,{cN:"meta-string"})]},f=[a,l,u,_,o,w,e.HCM,{cN:"class",bK:"class module struct",e:"$|;",i:/=/,c:[e.HCM,e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<"}]},{cN:"class",bK:"lib enum union",e:"$|;",i:/=/,c:[e.HCM,e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"})],r:10},{cN:"function",bK:"def",e:/\B\b/,c:[e.inherit(e.TM,{b:n,endsParent:!0})]},{cN:"function",bK:"fun macro",e:/\B\b/,c:[e.inherit(e.TM,{b:n,endsParent:!0})],r:5},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":",c:[l,{b:n}],r:0},{cN:"number",v:[{b:"\\b0b([01_]*[01])"+r},{b:"\\b0o([0-7_]*[0-7])"+r},{b:"\\b0x([A-Fa-f0-9_]*[A-Fa-f0-9])"+r},{b:"\\b(([0-9][0-9_]*[0-9]|[0-9])(\\.[0-9_]*[0-9])?([eE][+-]?[0-9_]*[0-9])?)"+r}],r:0}];return t.c=f,a.c=f.slice(1),{aliases:["cr"],l:c,k:s,c:f}});hljs.registerLanguage("rsl",function(e){return{k:{keyword:"float color point normal vector matrix while for if do return else break extern continue",built_in:"abs acos ambient area asin atan atmosphere attribute calculatenormal ceil cellnoise clamp comp concat cos degrees depth Deriv diffuse distance Du Dv environment exp faceforward filterstep floor format fresnel incident length lightsource log match max min mod noise normalize ntransform opposite option phong pnoise pow printf ptlined radians random reflect refract renderinfo round setcomp setxcomp setycomp setzcomp shadow sign sin smoothstep specular specularbrdf spline sqrt step tan texture textureinfo trace transform vtransform xcomp ycomp zcomp"},i:"|<-"}],i:/;/}});hljs.registerLanguage("bnf",function(e){return{c:[{cN:"attribute",b://},{b:/::=/,starts:{e:/$/,c:[{b://},e.CLCM,e.CBCM,e.ASM,e.QSM]}}]}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/\b-?[a-z\._]+\b/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}});hljs.registerLanguage("dockerfile",function(e){return{aliases:["docker"],cI:!0,k:"from maintainer expose env arg user onbuild stopsignal",c:[e.HCM,e.ASM,e.QSM,e.NM,{bK:"run cmd entrypoint volume add copy workdir label healthcheck shell",starts:{e:/[^\\]\n/,sL:"bash"}}],i:"",i:"\\n"}]},a,e.CLCM,e.CBCM]},i={cN:"variable",b:"\\&[a-z\\d_]*\\b"},r={cN:"meta-keyword",b:"/[a-z][a-z\\d-]*/"},d={cN:"symbol",b:"^\\s*[a-zA-Z_][a-zA-Z\\d_]*:"},n={cN:"params",b:"<",e:">",c:[c,i]},s={cN:"class",b:/[a-zA-Z_][a-zA-Z\d_@]*\s{/,e:/[{;=]/,rB:!0,eE:!0},t={cN:"class",b:"/\\s*{",e:"};",r:10,c:[i,r,d,s,n,e.CLCM,e.CBCM,c,a]};return{k:"",c:[t,i,r,d,s,n,e.CLCM,e.CBCM,c,a,b,{b:e.IR+"::",k:""}]}});hljs.registerLanguage("prolog",function(c){var b={b:/[a-z][A-Za-z0-9_]*/,r:0},r={cN:"symbol",v:[{b:/[A-Z][a-zA-Z0-9_]*/},{b:/_[A-Za-z0-9_]*/}],r:0},e={b:/\(/,e:/\)/,r:0},n={b:/\[/,e:/\]/},a={cN:"comment",b:/%/,e:/$/,c:[c.PWM]},t={cN:"string",b:/`/,e:/`/,c:[c.BE]},g={cN:"string",b:/0\'(\\\'|.)/},s={cN:"string",b:/0\'\\s/},o={b:/:-/},N=[b,r,e,o,n,a,c.CBCM,c.QSM,c.ASM,t,g,s,c.CNM];return e.c=N,n.c=N,{c:N.concat([{b:/\.$/}])}});hljs.registerLanguage("1c",function(s){var x="[A-Za-zА-Яа-яёЁ_][A-Za-zА-Яа-яёЁ_0-9]+",o="далее ",m="возврат вызватьисключение выполнить для если и из или иначе иначеесли исключение каждого конецесли конецпопытки конеццикла не новый перейти перем по пока попытка прервать продолжить тогда цикл экспорт ",t=o+m,l="загрузитьизфайла ",e="вебклиент вместо внешнеесоединение клиент конецобласти мобильноеприложениеклиент мобильноеприложениесервер наклиенте наклиентенасервере наклиентенасерверебезконтекста насервере насерверебезконтекста область перед после сервер толстыйклиентобычноеприложение толстыйклиентуправляемоеприложение тонкийклиент ",n=l+e,a="разделительстраниц разделительстрок символтабуляции ",d="ansitooem oemtoansi ввестивидсубконто ввестиперечисление ввестипериод ввестиплансчетов выбранныйплансчетов датагод датамесяц датачисло заголовоксистемы значениевстроку значениеизстроки каталогиб каталогпользователя кодсимв конгода конецпериодаби конецрассчитанногопериодаби конецстандартногоинтервала конквартала конмесяца коннедели лог лог10 максимальноеколичествосубконто названиеинтерфейса названиенабораправ назначитьвид назначитьсчет найтиссылки началопериодаби началостандартногоинтервала начгода начквартала начмесяца начнедели номерднягода номерднянедели номернеделигода обработкаожидания основнойжурналрасчетов основнойплансчетов основнойязык очиститьокносообщений периодстр получитьвремята получитьдатута получитьдокументта получитьзначенияотбора получитьпозициюта получитьпустоезначение получитьта префиксавтонумерации пропись пустоезначение разм разобратьпозициюдокумента рассчитатьрегистрына рассчитатьрегистрыпо симв создатьобъект статусвозврата стрколичествострок сформироватьпозициюдокумента счетпокоду текущеевремя типзначения типзначениястр установитьтана установитьтапо фиксшаблон шаблон ",i="acos asin atan base64значение base64строка cos exp log log10 pow sin sqrt tan xmlзначение xmlстрока xmlтип xmlтипзнч активноеокно безопасныйрежим безопасныйрежимразделенияданных булево ввестидату ввестизначение ввестистроку ввестичисло возможностьчтенияxml вопрос восстановитьзначение врег выгрузитьжурналрегистрации выполнитьобработкуоповещения выполнитьпроверкуправдоступа вычислить год данныеформывзначение дата день деньгода деньнедели добавитьмесяц заблокироватьданныедляредактирования заблокироватьработупользователя завершитьработусистемы загрузитьвнешнююкомпоненту закрытьсправку записатьjson записатьxml записатьдатуjson записьжурналарегистрации заполнитьзначениясвойств запроситьразрешениепользователя запуститьприложение запуститьсистему зафиксироватьтранзакцию значениевданныеформы значениевстрокувнутр значениевфайл значениезаполнено значениеизстрокивнутр значениеизфайла изxmlтипа импортмоделиxdto имякомпьютера имяпользователя инициализироватьпредопределенныеданные информацияобошибке каталогбиблиотекимобильногоустройства каталогвременныхфайлов каталогдокументов каталогпрограммы кодироватьстроку кодлокализацииинформационнойбазы кодсимвола командасистемы конецгода конецдня конецквартала конецмесяца конецминуты конецнедели конецчаса конфигурациябазыданныхизмененадинамически конфигурацияизменена копироватьданныеформы копироватьфайл краткоепредставлениеошибки лев макс местноевремя месяц мин минута монопольныйрежим найти найтинедопустимыесимволыxml найтиокнопонавигационнойссылке найтипомеченныенаудаление найтипоссылкам найтифайлы началогода началодня началоквартала началомесяца началоминуты началонедели началочаса начатьзапросразрешенияпользователя начатьзапускприложения начатькопированиефайла начатьперемещениефайла начатьподключениевнешнейкомпоненты начатьподключениерасширенияработыскриптографией начатьподключениерасширенияработысфайлами начатьпоискфайлов начатьполучениекаталогавременныхфайлов начатьполучениекаталогадокументов начатьполучениерабочегокаталогаданныхпользователя начатьполучениефайлов начатьпомещениефайла начатьпомещениефайлов начатьсозданиедвоичныхданныхизфайла начатьсозданиекаталога начатьтранзакцию начатьудалениефайлов начатьустановкувнешнейкомпоненты начатьустановкурасширенияработыскриптографией начатьустановкурасширенияработысфайлами неделягода необходимостьзавершениясоединения номерсеансаинформационнойбазы номерсоединенияинформационнойбазы нрег нстр обновитьинтерфейс обновитьнумерациюобъектов обновитьповторноиспользуемыезначения обработкапрерыванияпользователя объединитьфайлы окр описаниеошибки оповестить оповеститьобизменении отключитьобработчикзапросанастроекклиенталицензирования отключитьобработчикожидания отключитьобработчикоповещения открытьзначение открытьиндекссправки открытьсодержаниесправки открытьсправку открытьформу открытьформумодально отменитьтранзакцию очиститьжурналрегистрации очиститьнастройкипользователя очиститьсообщения параметрыдоступа перейтипонавигационнойссылке переместитьфайл подключитьвнешнююкомпоненту подключитьобработчикзапросанастроекклиенталицензирования подключитьобработчикожидания подключитьобработчикоповещения подключитьрасширениеработыскриптографией подключитьрасширениеработысфайлами подробноепредставлениеошибки показатьвводдаты показатьвводзначения показатьвводстроки показатьвводчисла показатьвопрос показатьзначение показатьинформациюобошибке показатьнакарте показатьоповещениепользователя показатьпредупреждение полноеимяпользователя получитьcomобъект получитьxmlтип получитьадреспоместоположению получитьблокировкусеансов получитьвремязавершенияспящегосеанса получитьвремязасыпанияпассивногосеанса получитьвремяожиданияблокировкиданных получитьданныевыбора получитьдополнительныйпараметрклиенталицензирования получитьдопустимыекодылокализации получитьдопустимыечасовыепояса получитьзаголовокклиентскогоприложения получитьзаголовоксистемы получитьзначенияотборажурналарегистрации получитьидентификаторконфигурации получитьизвременногохранилища получитьимявременногофайла получитьимяклиенталицензирования получитьинформациюэкрановклиента получитьиспользованиежурналарегистрации получитьиспользованиесобытияжурналарегистрации получитькраткийзаголовокприложения получитьмакетоформления получитьмаскувсефайлы получитьмаскувсефайлыклиента получитьмаскувсефайлысервера получитьместоположениепоадресу получитьминимальнуюдлинупаролейпользователей получитьнавигационнуюссылку получитьнавигационнуюссылкуинформационнойбазы получитьобновлениеконфигурациибазыданных получитьобновлениепредопределенныхданныхинформационнойбазы получитьобщиймакет получитьобщуюформу получитьокна получитьоперативнуюотметкувремени получитьотключениебезопасногорежима получитьпараметрыфункциональныхопцийинтерфейса получитьполноеимяпредопределенногозначения получитьпредставлениянавигационныхссылок получитьпроверкусложностипаролейпользователей получитьразделительпути получитьразделительпутиклиента получитьразделительпутисервера получитьсеансыинформационнойбазы получитьскоростьклиентскогосоединения получитьсоединенияинформационнойбазы получитьсообщенияпользователю получитьсоответствиеобъектаиформы получитьсоставстандартногоинтерфейсаodata получитьструктурухранениябазыданных получитьтекущийсеансинформационнойбазы получитьфайл получитьфайлы получитьформу получитьфункциональнуюопцию получитьфункциональнуюопциюинтерфейса получитьчасовойпоясинформационнойбазы пользователиос поместитьвовременноехранилище поместитьфайл поместитьфайлы прав праводоступа предопределенноезначение представлениекодалокализации представлениепериода представлениеправа представлениеприложения представлениесобытияжурналарегистрации представлениечасовогопояса предупреждение прекратитьработусистемы привилегированныйрежим продолжитьвызов прочитатьjson прочитатьxml прочитатьдатуjson пустаястрока рабочийкаталогданныхпользователя разблокироватьданныедляредактирования разделитьфайл разорватьсоединениесвнешнимисточникомданных раскодироватьстроку рольдоступна секунда сигнал символ скопироватьжурналрегистрации смещениелетнеговремени смещениестандартноговремени соединитьбуферыдвоичныхданных создатькаталог создатьфабрикуxdto сокрл сокрлп сокрп сообщить состояние сохранитьзначение сохранитьнастройкипользователя сред стрдлина стрзаканчиваетсяна стрзаменить стрнайти стрначинаетсяс строка строкасоединенияинформационнойбазы стрполучитьстроку стрразделить стрсоединить стрсравнить стрчисловхождений стрчислострок стршаблон текущаядата текущаядатасеанса текущаяуниверсальнаядата текущаяуниверсальнаядатавмиллисекундах текущийвариантинтерфейсаклиентскогоприложения текущийвариантосновногошрифтаклиентскогоприложения текущийкодлокализации текущийрежимзапуска текущийязык текущийязыксистемы тип типзнч транзакцияактивна трег удалитьданныеинформационнойбазы удалитьизвременногохранилища удалитьобъекты удалитьфайлы универсальноевремя установитьбезопасныйрежим установитьбезопасныйрежимразделенияданных установитьблокировкусеансов установитьвнешнююкомпоненту установитьвремязавершенияспящегосеанса установитьвремязасыпанияпассивногосеанса установитьвремяожиданияблокировкиданных установитьзаголовокклиентскогоприложения установитьзаголовоксистемы установитьиспользованиежурналарегистрации установитьиспользованиесобытияжурналарегистрации установитькраткийзаголовокприложения установитьминимальнуюдлинупаролейпользователей установитьмонопольныйрежим установитьнастройкиклиенталицензирования установитьобновлениепредопределенныхданныхинформационнойбазы установитьотключениебезопасногорежима установитьпараметрыфункциональныхопцийинтерфейса установитьпривилегированныйрежим установитьпроверкусложностипаролейпользователей установитьрасширениеработыскриптографией установитьрасширениеработысфайлами установитьсоединениесвнешнимисточникомданных установитьсоответствиеобъектаиформы установитьсоставстандартногоинтерфейсаodata установитьчасовойпоясинформационнойбазы установитьчасовойпояссеанса формат цел час часовойпояс часовойпояссеанса число числопрописью этоадресвременногохранилища ",c="wsссылки библиотекакартинок библиотекамакетовоформлениякомпоновкиданных библиотекастилей бизнеспроцессы внешниеисточникиданных внешниеобработки внешниеотчеты встроенныепокупки главныйинтерфейс главныйстиль документы доставляемыеуведомления журналыдокументов задачи информацияобинтернетсоединении использованиерабочейдаты историяработыпользователя константы критерииотбора метаданные обработки отображениерекламы отправкадоставляемыхуведомлений отчеты панельзадачос параметрзапуска параметрысеанса перечисления планывидоврасчета планывидовхарактеристик планыобмена планысчетов полнотекстовыйпоиск пользователиинформационнойбазы последовательности проверкавстроенныхпокупок рабочаядата расширенияконфигурации регистрыбухгалтерии регистрынакопления регистрырасчета регистрысведений регламентныезадания сериализаторxdto справочники средствагеопозиционирования средствакриптографии средствамультимедиа средстваотображениярекламы средствапочты средствателефонии фабрикаxdto файловыепотоки фоновыезадания хранилищанастроек хранилищевариантовотчетов хранилищенастроекданныхформ хранилищеобщихнастроек хранилищепользовательскихнастроекдинамическихсписков хранилищепользовательскихнастроекотчетов хранилищесистемныхнастроек ",r=a+d+i+c,p="webцвета windowsцвета windowsшрифты библиотекакартинок рамкистиля символы цветастиля шрифтыстиля ",b="автоматическоесохранениеданныхформывнастройках автонумерациявформе автораздвижениесерий анимациядиаграммы вариантвыравниванияэлементовизаголовков вариантуправлениявысотойтаблицы вертикальнаяпрокруткаформы вертикальноеположение вертикальноеположениеэлемента видгруппыформы виддекорацииформы виддополненияэлементаформы видизмененияданных видкнопкиформы видпереключателя видподписейкдиаграмме видполяформы видфлажка влияниеразмеранапузырекдиаграммы горизонтальноеположение горизонтальноеположениеэлемента группировкаколонок группировкаподчиненныхэлементовформы группыиэлементы действиеперетаскивания дополнительныйрежимотображения допустимыедействияперетаскивания интервалмеждуэлементамиформы использованиевывода использованиеполосыпрокрутки используемоезначениеточкибиржевойдиаграммы историявыборапривводе источникзначенийоситочекдиаграммы источникзначенияразмерапузырькадиаграммы категориягруппыкоманд максимумсерий начальноеотображениедерева начальноеотображениесписка обновлениетекстаредактирования ориентациядендрограммы ориентациядиаграммы ориентацияметокдиаграммы ориентацияметоксводнойдиаграммы ориентацияэлементаформы отображениевдиаграмме отображениевлегендедиаграммы отображениегруппыкнопок отображениезаголовкашкалыдиаграммы отображениезначенийсводнойдиаграммы отображениезначенияизмерительнойдиаграммы отображениеинтерваладиаграммыганта отображениекнопки отображениекнопкивыбора отображениеобсужденийформы отображениеобычнойгруппы отображениеотрицательныхзначенийпузырьковойдиаграммы отображениепанелипоиска отображениеподсказки отображениепредупрежденияприредактировании отображениеразметкиполосырегулирования отображениестраницформы отображениетаблицы отображениетекстазначениядиаграммыганта отображениеуправленияобычнойгруппы отображениефигурыкнопки палитрацветовдиаграммы поведениеобычнойгруппы поддержкамасштабадендрограммы поддержкамасштабадиаграммыганта поддержкамасштабасводнойдиаграммы поисквтаблицепривводе положениезаголовкаэлементаформы положениекартинкикнопкиформы положениекартинкиэлементаграфическойсхемы положениекоманднойпанелиформы положениекоманднойпанелиэлементаформы положениеопорнойточкиотрисовки положениеподписейкдиаграмме положениеподписейшкалызначенийизмерительнойдиаграммы положениесостоянияпросмотра положениестрокипоиска положениетекстасоединительнойлинии положениеуправленияпоиском положениешкалывремени порядокотображенияточекгоризонтальнойгистограммы порядоксерийвлегендедиаграммы размеркартинки расположениезаголовкашкалыдиаграммы растягиваниеповертикалидиаграммыганта режимавтоотображениясостояния режимвводастроктаблицы режимвыборанезаполненного режимвыделениядаты режимвыделениястрокитаблицы режимвыделениятаблицы режимизмененияразмера режимизменениясвязанногозначения режимиспользованиядиалогапечати режимиспользованияпараметракоманды режиммасштабированияпросмотра режимосновногоокнаклиентскогоприложения режимоткрытияокнаформы режимотображениявыделения режимотображениягеографическойсхемы режимотображениязначенийсерии режимотрисовкисеткиграфическойсхемы режимполупрозрачностидиаграммы режимпробеловдиаграммы режимразмещениянастранице режимредактированияколонки режимсглаживаниядиаграммы режимсглаживанияиндикатора режимсписказадач сквозноевыравнивание сохранениеданныхформывнастройках способзаполнениятекстазаголовкашкалыдиаграммы способопределенияограничивающегозначениядиаграммы стандартнаягруппакоманд стандартноеоформление статусоповещенияпользователя стильстрелки типаппроксимациилиниитрендадиаграммы типдиаграммы типединицышкалывремени типимпортасерийслоягеографическойсхемы типлиниигеографическойсхемы типлиниидиаграммы типмаркерагеографическойсхемы типмаркерадиаграммы типобластиоформления типорганизацииисточникаданныхгеографическойсхемы типотображениясериислоягеографическойсхемы типотображенияточечногообъектагеографическойсхемы типотображенияшкалыэлементалегендыгеографическойсхемы типпоискаобъектовгеографическойсхемы типпроекциигеографическойсхемы типразмещенияизмерений типразмещенияреквизитовизмерений типрамкиэлементауправления типсводнойдиаграммы типсвязидиаграммыганта типсоединениязначенийпосериямдиаграммы типсоединенияточекдиаграммы типсоединительнойлинии типстороныэлементаграфическойсхемы типформыотчета типшкалырадарнойдиаграммы факторлиниитрендадиаграммы фигуракнопки фигурыграфическойсхемы фиксациявтаблице форматдняшкалывремени форматкартинки ширинаподчиненныхэлементовформы ",w="виддвижениябухгалтерии виддвижениянакопления видпериодарегистрарасчета видсчета видточкимаршрутабизнеспроцесса использованиеагрегатарегистранакопления использованиегруппиэлементов использованиережимапроведения использованиесреза периодичностьагрегатарегистранакопления режимавтовремя режимзаписидокумента режимпроведениядокумента ",h="авторегистрацияизменений допустимыйномерсообщения отправкаэлементаданных получениеэлементаданных ",j="использованиерасшифровкитабличногодокумента ориентациястраницы положениеитоговколоноксводнойтаблицы положениеитоговстроксводнойтаблицы положениетекстаотносительнокартинки расположениезаголовкагруппировкитабличногодокумента способчтениязначенийтабличногодокумента типдвустороннейпечати типзаполненияобластитабличногодокумента типкурсоровтабличногодокумента типлиниирисункатабличногодокумента типлинииячейкитабличногодокумента типнаправленияпереходатабличногодокумента типотображениявыделениятабличногодокумента типотображениялинийсводнойтаблицы типразмещениятекстатабличногодокумента типрисункатабличногодокумента типсмещениятабличногодокумента типузоратабличногодокумента типфайлатабличногодокумента точностьпечати чередованиерасположениястраниц ",z="отображениевремениэлементовпланировщика ",f="типфайлаформатированногодокумента ",k="обходрезультатазапроса типзаписизапроса ",u="видзаполнениярасшифровкипостроителяотчета типдобавленияпредставлений типизмеренияпостроителяотчета типразмещенияитогов ",y="доступкфайлу режимдиалогавыборафайла режимоткрытияфайла ",N="типизмеренияпостроителязапроса ",g="видданныханализа методкластеризации типединицыинтервалавременианализаданных типзаполнениятаблицырезультатаанализаданных типиспользованиячисловыхзначенийанализаданных типисточникаданныхпоискаассоциаций типколонкианализаданныхдереворешений типколонкианализаданныхкластеризация типколонкианализаданныхобщаястатистика типколонкианализаданныхпоискассоциаций типколонкианализаданныхпоискпоследовательностей типколонкимоделипрогноза типмерырасстоянияанализаданных типотсеченияправилассоциации типполяанализаданных типстандартизациианализаданных типупорядочиванияправилассоциациианализаданных типупорядочиванияшаблоновпоследовательностейанализаданных типупрощениядереварешений ",E="wsнаправлениепараметра вариантxpathxs вариантзаписидатыjson вариантпростоготипаxs видгруппымоделиxs видфасетаxdto действиепостроителяdom завершенностьпростоготипаxs завершенностьсоставноготипаxs завершенностьсхемыxs запрещенныеподстановкиxs исключениягруппподстановкиxs категорияиспользованияатрибутаxs категорияограниченияидентичностиxs категорияограниченияпространствименxs методнаследованияxs модельсодержимогоxs назначениетипаxml недопустимыеподстановкиxs обработкапробельныхсимволовxs обработкасодержимогоxs ограничениезначенияxs параметрыотбораузловdom переносстрокjson позициявдокументеdom пробельныесимволыxml типатрибутаxml типзначенияjson типканоническогоxml типкомпонентыxs типпроверкиxml типрезультатаdomxpath типузлаdom типузлаxml формаxml формапредставленияxs форматдатыjson экранированиесимволовjson ",M="видсравнениякомпоновкиданных действиеобработкирасшифровкикомпоновкиданных направлениесортировкикомпоновкиданных расположениевложенныхэлементоврезультатакомпоновкиданных расположениеитоговкомпоновкиданных расположениегруппировкикомпоновкиданных расположениеполейгруппировкикомпоновкиданных расположениеполякомпоновкиданных расположениереквизитовкомпоновкиданных расположениересурсовкомпоновкиданных типбухгалтерскогоостаткакомпоновкиданных типвыводатекстакомпоновкиданных типгруппировкикомпоновкиданных типгруппыэлементовотборакомпоновкиданных типдополненияпериодакомпоновкиданных типзаголовкаполейкомпоновкиданных типмакетагруппировкикомпоновкиданных типмакетаобластикомпоновкиданных типостаткакомпоновкиданных типпериодакомпоновкиданных типразмещениятекстакомпоновкиданных типсвязинаборовданныхкомпоновкиданных типэлементарезультатакомпоновкиданных расположениелегендыдиаграммыкомпоновкиданных типпримененияотборакомпоновкиданных режимотображенияэлементанастройкикомпоновкиданных режимотображениянастроеккомпоновкиданных состояниеэлементанастройкикомпоновкиданных способвосстановлениянастроеккомпоновкиданных режимкомпоновкирезультата использованиепараметракомпоновкиданных автопозицияресурсовкомпоновкиданных вариантиспользованиягруппировкикомпоновкиданных расположениересурсоввдиаграммекомпоновкиданных фиксациякомпоновкиданных использованиеусловногооформлениякомпоновкиданных ",_="важностьинтернетпочтовогосообщения обработкатекстаинтернетпочтовогосообщения способкодированияинтернетпочтовоговложения способкодированиянеasciiсимволовинтернетпочтовогосообщения типтекстапочтовогосообщения протоколинтернетпочты статусразборапочтовогосообщения ",v="режимтранзакциизаписижурналарегистрации статустранзакциизаписижурналарегистрации уровеньжурналарегистрации ",A="расположениехранилищасертификатовкриптографии режимвключениясертификатовкриптографии режимпроверкисертификатакриптографии типхранилищасертификатовкриптографии ",C="кодировкаименфайловвzipфайле методсжатияzip методшифрованияzip режимвосстановленияпутейфайловzip режимобработкиподкаталоговzip режимсохраненияпутейzip уровеньсжатияzip ",L="звуковоеоповещение направлениепереходакстроке позициявпотоке порядокбайтов режимблокировкиданных режимуправленияблокировкойданных сервисвстроенныхпокупок состояниефоновогозадания типподписчикадоставляемыхуведомлений уровеньиспользованиязащищенногосоединенияftp ",Z="направлениепорядкасхемызапроса типдополненияпериодамисхемызапроса типконтрольнойточкисхемызапроса типобъединениясхемызапроса типпараметрадоступнойтаблицысхемызапроса типсоединениясхемызапроса ",$="httpметод автоиспользованиеобщегореквизита автопрефиксномеразадачи вариантвстроенногоязыка видиерархии видрегистранакопления видтаблицывнешнегоисточникаданных записьдвиженийприпроведении заполнениепоследовательностей индексирование использованиебазыпланавидоврасчета использованиебыстроговыбора использованиеобщегореквизита использованиеподчинения использованиеполнотекстовогопоиска использованиеразделяемыхданныхобщегореквизита использованиереквизита назначениеиспользованияприложения назначениерасширенияконфигурации направлениепередачи обновлениепредопределенныхданных оперативноепроведение основноепредставлениевидарасчета основноепредставлениевидахарактеристики основноепредставлениезадачи основноепредставлениепланаобмена основноепредставлениесправочника основноепредставлениесчета перемещениеграницыприпроведении периодичностьномерабизнеспроцесса периодичностьномерадокумента периодичностьрегистрарасчета периодичностьрегистрасведений повторноеиспользованиевозвращаемыхзначений полнотекстовыйпоискпривводепостроке принадлежностьобъекта проведение разделениеаутентификацииобщегореквизита разделениеданныхобщегореквизита разделениерасширенийконфигурацииобщегореквизита режимавтонумерацииобъектов режимзаписирегистра режимиспользованиямодальности режимиспользованиясинхронныхвызововрасширенийплатформыивнешнихкомпонент режимповторногоиспользованиясеансов режимполученияданныхвыборапривводепостроке режимсовместимости режимсовместимостиинтерфейса режимуправленияблокировкойданныхпоумолчанию сериикодовпланавидовхарактеристик сериикодовпланасчетов сериикодовсправочника созданиепривводе способвыбора способпоискастрокипривводепостроке способредактирования типданныхтаблицывнешнегоисточникаданных типкодапланавидоврасчета типкодасправочника типмакета типномерабизнеспроцесса типномерадокумента типномеразадачи типформы удалениедвижений ",q="важностьпроблемыприменениярасширенияконфигурации вариантинтерфейсаклиентскогоприложения вариантмасштабаформклиентскогоприложения вариантосновногошрифтаклиентскогоприложения вариантстандартногопериода вариантстандартнойдатыначала видграницы видкартинки видотображенияполнотекстовогопоиска видрамки видсравнения видцвета видчисловогозначения видшрифта допустимаядлина допустимыйзнак использованиеbyteordermark использованиеметаданныхполнотекстовогопоиска источникрасширенийконфигурации клавиша кодвозвратадиалога кодировкаxbase кодировкатекста направлениепоиска направлениесортировки обновлениепредопределенныхданных обновлениеприизмененииданных отображениепанелиразделов проверказаполнения режимдиалогавопрос режимзапускаклиентскогоприложения режимокругления режимоткрытияформприложения режимполнотекстовогопоиска скоростьклиентскогосоединения состояниевнешнегоисточникаданных состояниеобновленияконфигурациибазыданных способвыборасертификатаwindows способкодированиястроки статуссообщения типвнешнейкомпоненты типплатформы типповеденияклавишиenter типэлементаинформацииовыполненииобновленияконфигурациибазыданных уровеньизоляциитранзакций хешфункция частидаты",B=p+b+w+h+j+z+f+k+u+y+N+g+E+M+_+v+A+C+L+Z+$+q,I="comобъект ftpсоединение httpзапрос httpсервисответ httpсоединение wsопределения wsпрокси xbase анализданных аннотацияxs блокировкаданных буфердвоичныхданных включениеxs выражениекомпоновкиданных генераторслучайныхчисел географическаясхема географическиекоординаты графическаясхема группамоделиxs данныерасшифровкикомпоновкиданных двоичныеданные дендрограмма диаграмма диаграммаганта диалогвыборафайла диалогвыборацвета диалогвыборашрифта диалограсписаниярегламентногозадания диалогредактированиястандартногопериода диапазон документdom документhtml документацияxs доставляемоеуведомление записьdom записьfastinfoset записьhtml записьjson записьxml записьzipфайла записьданных записьтекста записьузловdom запрос защищенноесоединениеopenssl значенияполейрасшифровкикомпоновкиданных извлечениетекста импортxs интернетпочта интернетпочтовоесообщение интернетпочтовыйпрофиль интернетпрокси интернетсоединение информациядляприложенияxs использованиеатрибутаxs использованиесобытияжурналарегистрации источникдоступныхнастроеккомпоновкиданных итераторузловdom картинка квалификаторыдаты квалификаторыдвоичныхданных квалификаторыстроки квалификаторычисла компоновщикмакетакомпоновкиданных компоновщикнастроеккомпоновкиданных конструктормакетаоформлениякомпоновкиданных конструкторнастроеккомпоновкиданных конструкторформатнойстроки линия макеткомпоновкиданных макетобластикомпоновкиданных макетоформлениякомпоновкиданных маскаxs менеджеркриптографии наборсхемxml настройкикомпоновкиданных настройкисериализацииjson обработкакартинок обработкарасшифровкикомпоновкиданных обходдереваdom объявлениеатрибутаxs объявлениенотацииxs объявлениеэлементаxs описаниеиспользованиясобытиядоступжурналарегистрации описаниеиспользованиясобытияотказвдоступежурналарегистрации описаниеобработкирасшифровкикомпоновкиданных описаниепередаваемогофайла описаниетипов определениегруппыатрибутовxs определениегруппымоделиxs определениеограниченияидентичностиxs определениепростоготипаxs определениесоставноготипаxs определениетипадокументаdom определенияxpathxs отборкомпоновкиданных пакетотображаемыхдокументов параметрвыбора параметркомпоновкиданных параметрызаписиjson параметрызаписиxml параметрычтенияxml переопределениеxs планировщик полеанализаданных полекомпоновкиданных построительdom построительзапроса построительотчета построительотчетаанализаданных построительсхемxml поток потоквпамяти почта почтовоесообщение преобразованиеxsl преобразованиекканоническомуxml процессорвыводарезультатакомпоновкиданныхвколлекциюзначений процессорвыводарезультатакомпоновкиданныхвтабличныйдокумент процессоркомпоновкиданных разыменовательпространствименdom рамка расписаниерегламентногозадания расширенноеимяxml результатчтенияданных своднаядиаграмма связьпараметравыбора связьпотипу связьпотипукомпоновкиданных сериализаторxdto сертификатклиентаwindows сертификатклиентафайл сертификаткриптографии сертификатыудостоверяющихцентровwindows сертификатыудостоверяющихцентровфайл сжатиеданных системнаяинформация сообщениепользователю сочетаниеклавиш сравнениезначений стандартнаядатаначала стандартныйпериод схемаxml схемакомпоновкиданных табличныйдокумент текстовыйдокумент тестируемоеприложение типданныхxml уникальныйидентификатор фабрикаxdto файл файловыйпоток фасетдлиныxs фасетколичестваразрядовдробнойчастиxs фасетмаксимальноговключающегозначенияxs фасетмаксимальногоисключающегозначенияxs фасетмаксимальнойдлиныxs фасетминимальноговключающегозначенияxs фасетминимальногоисключающегозначенияxs фасетминимальнойдлиныxs фасетобразцаxs фасетобщегоколичестваразрядовxs фасетперечисленияxs фасетпробельныхсимволовxs фильтрузловdom форматированнаястрока форматированныйдокумент фрагментxs хешированиеданных хранилищезначения цвет чтениеfastinfoset чтениеhtml чтениеjson чтениеxml чтениеzipфайла чтениеданных чтениетекста чтениеузловdom шрифт элементрезультатакомпоновкиданных ",P="comsafearray деревозначений массив соответствие списокзначений структура таблицазначений фиксированнаяструктура фиксированноесоответствие фиксированныймассив ",T=I+P,W="null истина ложь неопределено",D=s.inherit(s.NM),F={cN:"string",b:'"|\\|',e:'"|$',c:[{b:'""'}]},G={b:"'",e:"'",eB:!0,eE:!0,c:[{cN:"number",b:"\\d{4}([\\.\\\\/:-]?\\d{2}){0,5}"}]},H=s.inherit(s.CLCM),J={cN:"meta",l:x,b:"#|&",e:"$",k:{"meta-keyword":t+n},c:[H]},K={cN:"symbol",b:"~",e:";|:",eE:!0},O={cN:"function",l:x,v:[{b:"процедура|функция",e:"\\)",k:"процедура функция"},{b:"конецпроцедуры|конецфункции",k:"конецпроцедуры конецфункции"}],c:[{b:"\\(",e:"\\)",endsParent:!0,c:[{cN:"params",l:x,b:x,e:",",eE:!0,eW:!0,k:{keyword:"знач",literal:W},c:[D,F,G]},H]},s.inherit(s.TM,{b:x})]};return{cI:!0,l:x,k:{keyword:t,built_in:r,"class":B,type:T,literal:W},c:[J,O,H,K,D,F,G]}});hljs.registerLanguage("thrift",function(e){var t="bool byte i16 i32 i64 double string binary";return{k:{keyword:"namespace const typedef struct enum service exception void oneway set list map required optional",built_in:t,literal:"true false"},c:[e.QSM,e.NM,e.CLCM,e.CBCM,{cN:"class",bK:"struct enum service exception",e:/\{/,i:/\n/,c:[e.inherit(e.TM,{starts:{eW:!0,eE:!0}})]},{b:"\\b(set|list|map)\\s*<",e:">",k:t,c:["self"]}]}});hljs.registerLanguage("gauss",function(e){var t={keyword:"and bool break call callexe checkinterrupt clear clearg closeall cls comlog compile continue create debug declare delete disable dlibrary dllcall do dos ed edit else elseif enable end endfor endif endp endo errorlog errorlogat expr external fn for format goto gosub graph if keyword let lib library line load loadarray loadexe loadf loadk loadm loadp loads loadx local locate loopnextindex lprint lpwidth lshow matrix msym ndpclex new not open or output outwidth plot plotsym pop prcsn print printdos proc push retp return rndcon rndmod rndmult rndseed run save saveall screen scroll setarray show sparse stop string struct system trace trap threadfor threadendfor threadbegin threadjoin threadstat threadend until use while winprint",built_in:"abs acf aconcat aeye amax amean AmericanBinomCall AmericanBinomCall_Greeks AmericanBinomCall_ImpVol AmericanBinomPut AmericanBinomPut_Greeks AmericanBinomPut_ImpVol AmericanBSCall AmericanBSCall_Greeks AmericanBSCall_ImpVol AmericanBSPut AmericanBSPut_Greeks AmericanBSPut_ImpVol amin amult annotationGetDefaults annotationSetBkd annotationSetFont annotationSetLineColor annotationSetLineStyle annotationSetLineThickness annualTradingDays arccos arcsin areshape arrayalloc arrayindex arrayinit arraytomat asciiload asclabel astd astds asum atan atan2 atranspose axmargin balance band bandchol bandcholsol bandltsol bandrv bandsolpd bar base10 begwind besselj bessely beta box boxcox cdfBeta cdfBetaInv cdfBinomial cdfBinomialInv cdfBvn cdfBvn2 cdfBvn2e cdfCauchy cdfCauchyInv cdfChic cdfChii cdfChinc cdfChincInv cdfExp cdfExpInv cdfFc cdfFnc cdfFncInv cdfGam cdfGenPareto cdfHyperGeo cdfLaplace cdfLaplaceInv cdfLogistic cdfLogisticInv cdfmControlCreate cdfMvn cdfMvn2e cdfMvnce cdfMvne cdfMvt2e cdfMvtce cdfMvte cdfN cdfN2 cdfNc cdfNegBinomial cdfNegBinomialInv cdfNi cdfPoisson cdfPoissonInv cdfRayleigh cdfRayleighInv cdfTc cdfTci cdfTnc cdfTvn cdfWeibull cdfWeibullInv cdir ceil ChangeDir chdir chiBarSquare chol choldn cholsol cholup chrs close code cols colsf combinate combinated complex con cond conj cons ConScore contour conv convertsatostr convertstrtosa corrm corrms corrvc corrx corrxs cos cosh counts countwts crossprd crout croutp csrcol csrlin csvReadM csvReadSA cumprodc cumsumc curve cvtos datacreate datacreatecomplex datalist dataload dataloop dataopen datasave date datestr datestring datestrymd dayinyr dayofweek dbAddDatabase dbClose dbCommit dbCreateQuery dbExecQuery dbGetConnectOptions dbGetDatabaseName dbGetDriverName dbGetDrivers dbGetHostName dbGetLastErrorNum dbGetLastErrorText dbGetNumericalPrecPolicy dbGetPassword dbGetPort dbGetTableHeaders dbGetTables dbGetUserName dbHasFeature dbIsDriverAvailable dbIsOpen dbIsOpenError dbOpen dbQueryBindValue dbQueryClear dbQueryCols dbQueryExecPrepared dbQueryFetchAllM dbQueryFetchAllSA dbQueryFetchOneM dbQueryFetchOneSA dbQueryFinish dbQueryGetBoundValue dbQueryGetBoundValues dbQueryGetField dbQueryGetLastErrorNum dbQueryGetLastErrorText dbQueryGetLastInsertID dbQueryGetLastQuery dbQueryGetPosition dbQueryIsActive dbQueryIsForwardOnly dbQueryIsNull dbQueryIsSelect dbQueryIsValid dbQueryPrepare dbQueryRows dbQuerySeek dbQuerySeekFirst dbQuerySeekLast dbQuerySeekNext dbQuerySeekPrevious dbQuerySetForwardOnly dbRemoveDatabase dbRollback dbSetConnectOptions dbSetDatabaseName dbSetHostName dbSetNumericalPrecPolicy dbSetPort dbSetUserName dbTransaction DeleteFile delif delrows denseToSp denseToSpRE denToZero design det detl dfft dffti diag diagrv digamma doswin DOSWinCloseall DOSWinOpen dotfeq dotfeqmt dotfge dotfgemt dotfgt dotfgtmt dotfle dotflemt dotflt dotfltmt dotfne dotfnemt draw drop dsCreate dstat dstatmt dstatmtControlCreate dtdate dtday dttime dttodtv dttostr dttoutc dtvnormal dtvtodt dtvtoutc dummy dummybr dummydn eig eigh eighv eigv elapsedTradingDays endwind envget eof eqSolve eqSolvemt eqSolvemtControlCreate eqSolvemtOutCreate eqSolveset erf erfc erfccplx erfcplx error etdays ethsec etstr EuropeanBinomCall EuropeanBinomCall_Greeks EuropeanBinomCall_ImpVol EuropeanBinomPut EuropeanBinomPut_Greeks EuropeanBinomPut_ImpVol EuropeanBSCall EuropeanBSCall_Greeks EuropeanBSCall_ImpVol EuropeanBSPut EuropeanBSPut_Greeks EuropeanBSPut_ImpVol exctsmpl exec execbg exp extern eye fcheckerr fclearerr feq feqmt fflush fft ffti fftm fftmi fftn fge fgemt fgets fgetsa fgetsat fgetst fgt fgtmt fileinfo filesa fle flemt floor flt fltmt fmod fne fnemt fonts fopen formatcv formatnv fputs fputst fseek fstrerror ftell ftocv ftos ftostrC gamma gammacplx gammaii gausset gdaAppend gdaCreate gdaDStat gdaDStatMat gdaGetIndex gdaGetName gdaGetNames gdaGetOrders gdaGetType gdaGetTypes gdaGetVarInfo gdaIsCplx gdaLoad gdaPack gdaRead gdaReadByIndex gdaReadSome gdaReadSparse gdaReadStruct gdaReportVarInfo gdaSave gdaUpdate gdaUpdateAndPack gdaVars gdaWrite gdaWrite32 gdaWriteSome getarray getdims getf getGAUSShome getmatrix getmatrix4D getname getnamef getNextTradingDay getNextWeekDay getnr getorders getpath getPreviousTradingDay getPreviousWeekDay getRow getscalar3D getscalar4D getTrRow getwind glm gradcplx gradMT gradMTm gradMTT gradMTTm gradp graphprt graphset hasimag header headermt hess hessMT hessMTg hessMTgw hessMTm hessMTmw hessMTT hessMTTg hessMTTgw hessMTTm hessMTw hessp hist histf histp hsec imag indcv indexcat indices indices2 indicesf indicesfn indnv indsav integrate1d integrateControlCreate intgrat2 intgrat3 inthp1 inthp2 inthp3 inthp4 inthpControlCreate intquad1 intquad2 intquad3 intrleav intrleavsa intrsect intsimp inv invpd invswp iscplx iscplxf isden isinfnanmiss ismiss key keyav keyw lag lag1 lagn lapEighb lapEighi lapEighvb lapEighvi lapgEig lapgEigh lapgEighv lapgEigv lapgSchur lapgSvdcst lapgSvds lapgSvdst lapSvdcusv lapSvds lapSvdusv ldlp ldlsol linSolve listwise ln lncdfbvn lncdfbvn2 lncdfmvn lncdfn lncdfn2 lncdfnc lnfact lngammacplx lnpdfmvn lnpdfmvt lnpdfn lnpdft loadd loadstruct loadwind loess loessmt loessmtControlCreate log loglog logx logy lower lowmat lowmat1 ltrisol lu lusol machEpsilon make makevars makewind margin matalloc matinit mattoarray maxbytes maxc maxindc maxv maxvec mbesselei mbesselei0 mbesselei1 mbesseli mbesseli0 mbesseli1 meanc median mergeby mergevar minc minindc minv miss missex missrv moment momentd movingave movingaveExpwgt movingaveWgt nextindex nextn nextnevn nextwind ntos null null1 numCombinations ols olsmt olsmtControlCreate olsqr olsqr2 olsqrmt ones optn optnevn orth outtyp pacf packedToSp packr parse pause pdfCauchy pdfChi pdfExp pdfGenPareto pdfHyperGeo pdfLaplace pdfLogistic pdfn pdfPoisson pdfRayleigh pdfWeibull pi pinv pinvmt plotAddArrow plotAddBar plotAddBox plotAddHist plotAddHistF plotAddHistP plotAddPolar plotAddScatter plotAddShape plotAddTextbox plotAddTS plotAddXY plotArea plotBar plotBox plotClearLayout plotContour plotCustomLayout plotGetDefaults plotHist plotHistF plotHistP plotLayout plotLogLog plotLogX plotLogY plotOpenWindow plotPolar plotSave plotScatter plotSetAxesPen plotSetBar plotSetBarFill plotSetBarStacked plotSetBkdColor plotSetFill plotSetGrid plotSetLegend plotSetLineColor plotSetLineStyle plotSetLineSymbol plotSetLineThickness plotSetNewWindow plotSetTitle plotSetWhichYAxis plotSetXAxisShow plotSetXLabel plotSetXRange plotSetXTicInterval plotSetXTicLabel plotSetYAxisShow plotSetYLabel plotSetYRange plotSetZAxisShow plotSetZLabel plotSurface plotTS plotXY polar polychar polyeval polygamma polyint polymake polymat polymroot polymult polyroot pqgwin previousindex princomp printfm printfmt prodc psi putarray putf putvals pvCreate pvGetIndex pvGetParNames pvGetParVector pvLength pvList pvPack pvPacki pvPackm pvPackmi pvPacks pvPacksi pvPacksm pvPacksmi pvPutParVector pvTest pvUnpack QNewton QNewtonmt QNewtonmtControlCreate QNewtonmtOutCreate QNewtonSet QProg QProgmt QProgmtInCreate qqr qqre qqrep qr qre qrep qrsol qrtsol qtyr qtyre qtyrep quantile quantiled qyr qyre qyrep qz rank rankindx readr real reclassify reclassifyCuts recode recserar recsercp recserrc rerun rescale reshape rets rev rfft rffti rfftip rfftn rfftnp rfftp rndBernoulli rndBeta rndBinomial rndCauchy rndChiSquare rndCon rndCreateState rndExp rndGamma rndGeo rndGumbel rndHyperGeo rndi rndKMbeta rndKMgam rndKMi rndKMn rndKMnb rndKMp rndKMu rndKMvm rndLaplace rndLCbeta rndLCgam rndLCi rndLCn rndLCnb rndLCp rndLCu rndLCvm rndLogNorm rndMTu rndMVn rndMVt rndn rndnb rndNegBinomial rndp rndPoisson rndRayleigh rndStateSkip rndu rndvm rndWeibull rndWishart rotater round rows rowsf rref sampleData satostrC saved saveStruct savewind scale scale3d scalerr scalinfnanmiss scalmiss schtoc schur searchsourcepath seekr select selif seqa seqm setdif setdifsa setvars setvwrmode setwind shell shiftr sin singleindex sinh sleep solpd sortc sortcc sortd sorthc sorthcc sortind sortindc sortmc sortr sortrc spBiconjGradSol spChol spConjGradSol spCreate spDenseSubmat spDiagRvMat spEigv spEye spLDL spline spLU spNumNZE spOnes spreadSheetReadM spreadSheetReadSA spreadSheetWrite spScale spSubmat spToDense spTrTDense spTScalar spZeros sqpSolve sqpSolveMT sqpSolveMTControlCreate sqpSolveMTlagrangeCreate sqpSolveMToutCreate sqpSolveSet sqrt statements stdc stdsc stocv stof strcombine strindx strlen strput strrindx strsect strsplit strsplitPad strtodt strtof strtofcplx strtriml strtrimr strtrunc strtruncl strtruncpad strtruncr submat subscat substute subvec sumc sumr surface svd svd1 svd2 svdcusv svds svdusv sysstate tab tan tanh tempname threadBegin threadEnd threadEndFor threadFor threadJoin threadStat time timedt timestr timeutc title tkf2eps tkf2ps tocart todaydt toeplitz token topolar trapchk trigamma trimr trunc type typecv typef union unionsa uniqindx uniqindxsa unique uniquesa upmat upmat1 upper utctodt utctodtv utrisol vals varCovMS varCovXS varget vargetl varmall varmares varput varputl vartypef vcm vcms vcx vcxs vec vech vecr vector vget view viewxyz vlist vnamecv volume vput vread vtypecv wait waitc walkindex where window writer xlabel xlsGetSheetCount xlsGetSheetSize xlsGetSheetTypes xlsMakeRange xlsReadM xlsReadSA xlsWrite xlsWriteM xlsWriteSA xpnd xtics xy xyz ylabel ytics zeros zeta zlabel ztics cdfEmpirical dot h5create h5open h5read h5readAttribute h5write h5writeAttribute ldl plotAddErrorBar plotAddSurface plotCDFEmpirical plotSetColormap plotSetContourLabels plotSetLegendFont plotSetTextInterpreter plotSetXTicCount plotSetYTicCount plotSetZLevels powerm strjoin strtrim sylvester",literal:"DB_AFTER_LAST_ROW DB_ALL_TABLES DB_BATCH_OPERATIONS DB_BEFORE_FIRST_ROW DB_BLOB DB_EVENT_NOTIFICATIONS DB_FINISH_QUERY DB_HIGH_PRECISION DB_LAST_INSERT_ID DB_LOW_PRECISION_DOUBLE DB_LOW_PRECISION_INT32 DB_LOW_PRECISION_INT64 DB_LOW_PRECISION_NUMBERS DB_MULTIPLE_RESULT_SETS DB_NAMED_PLACEHOLDERS DB_POSITIONAL_PLACEHOLDERS DB_PREPARED_QUERIES DB_QUERY_SIZE DB_SIMPLE_LOCKING DB_SYSTEM_TABLES DB_TABLES DB_TRANSACTIONS DB_UNICODE DB_VIEWS"},a={cN:"meta",b:"#",e:"$",k:{"meta-keyword":"define definecs|10 undef ifdef ifndef iflight ifdllcall ifmac ifos2win ifunix else endif lineson linesoff srcfile srcline"},c:[{b:/\\\n/,r:0},{bK:"include",e:"$",k:{"meta-keyword":"include"},c:[{cN:"meta-string",b:'"',e:'"',i:"\\n"}]},e.CLCM,e.CBCM]},r=e.UIR+"\\s*\\(?",o=[{cN:"params",b:/\(/,e:/\)/,k:t,r:0,c:[e.CNM,e.CLCM,e.CBCM]}];return{aliases:["gss"],cI:!0,k:t,i:"(\\{[%#]|[%#]\\})",c:[e.CNM,e.CLCM,e.CBCM,e.C("@","@"),a,{cN:"string",b:'"',e:'"',c:[e.BE]},{cN:"function",bK:"proc keyword",e:";",eE:!0,k:t,c:[{b:r,rB:!0,c:[e.UTM],r:0},e.CNM,e.CLCM,e.CBCM,a].concat(o)},{cN:"function",bK:"fn",e:";",eE:!0,k:t,c:[{b:r+e.IR+"\\)?\\s*\\=\\s*",rB:!0,c:[e.UTM],r:0},e.CNM,e.CLCM,e.CBCM].concat(o)},{cN:"function",b:"\\bexternal (proc|keyword|fn)\\s+",e:";",eE:!0,k:t,c:[{b:r,rB:!0,c:[e.UTM],r:0},e.CLCM,e.CBCM]},{cN:"function",b:"\\bexternal (matrix|string|array|sparse matrix|struct "+e.IR+")\\s+",e:";",eE:!0,k:t,c:[e.CLCM,e.CBCM]}]}});hljs.registerLanguage("sqf",function(e){var t=e.getLanguage("cpp").exports,a={cN:"variable",b:/\b_+[a-zA-Z_]\w*/},o={cN:"title",b:/[a-zA-Z][a-zA-Z0-9]+_fnc_\w*/},r={cN:"string",v:[{b:'"',e:'"',c:[{b:'""',r:0}]},{b:"'",e:"'",c:[{b:"''",r:0}]}]};return{aliases:["sqf"],cI:!0,k:{keyword:"case catch default do else exit exitWith for forEach from if switch then throw to try waitUntil while with",built_in:"abs accTime acos action actionIDs actionKeys actionKeysImages actionKeysNames actionKeysNamesArray actionName actionParams activateAddons activatedAddons activateKey add3DENConnection add3DENEventHandler add3DENLayer addAction addBackpack addBackpackCargo addBackpackCargoGlobal addBackpackGlobal addCamShake addCuratorAddons addCuratorCameraArea addCuratorEditableObjects addCuratorEditingArea addCuratorPoints addEditorObject addEventHandler addGoggles addGroupIcon addHandgunItem addHeadgear addItem addItemCargo addItemCargoGlobal addItemPool addItemToBackpack addItemToUniform addItemToVest addLiveStats addMagazine addMagazineAmmoCargo addMagazineCargo addMagazineCargoGlobal addMagazineGlobal addMagazinePool addMagazines addMagazineTurret addMenu addMenuItem addMissionEventHandler addMPEventHandler addMusicEventHandler addOwnedMine addPlayerScores addPrimaryWeaponItem addPublicVariableEventHandler addRating addResources addScore addScoreSide addSecondaryWeaponItem addSwitchableUnit addTeamMember addToRemainsCollector addUniform addVehicle addVest addWaypoint addWeapon addWeaponCargo addWeaponCargoGlobal addWeaponGlobal addWeaponItem addWeaponPool addWeaponTurret agent agents AGLToASL aimedAtTarget aimPos airDensityRTD airportSide AISFinishHeal alive all3DENEntities allControls allCurators allCutLayers allDead allDeadMen allDisplays allGroups allMapMarkers allMines allMissionObjects allow3DMode allowCrewInImmobile allowCuratorLogicIgnoreAreas allowDamage allowDammage allowFileOperations allowFleeing allowGetIn allowSprint allPlayers allSites allTurrets allUnits allUnitsUAV allVariables ammo and animate animateDoor animateSource animationNames animationPhase animationSourcePhase animationState append apply armoryPoints arrayIntersect asin ASLToAGL ASLToATL assert assignAsCargo assignAsCargoIndex assignAsCommander assignAsDriver assignAsGunner assignAsTurret assignCurator assignedCargo assignedCommander assignedDriver assignedGunner assignedItems assignedTarget assignedTeam assignedVehicle assignedVehicleRole assignItem assignTeam assignToAirport atan atan2 atg ATLToASL attachedObject attachedObjects attachedTo attachObject attachTo attackEnabled backpack backpackCargo backpackContainer backpackItems backpackMagazines backpackSpaceFor behaviour benchmark binocular blufor boundingBox boundingBoxReal boundingCenter breakOut breakTo briefingName buildingExit buildingPos buttonAction buttonSetAction cadetMode call callExtension camCommand camCommit camCommitPrepared camCommitted camConstuctionSetParams camCreate camDestroy cameraEffect cameraEffectEnableHUD cameraInterest cameraOn cameraView campaignConfigFile camPreload camPreloaded camPrepareBank camPrepareDir camPrepareDive camPrepareFocus camPrepareFov camPrepareFovRange camPreparePos camPrepareRelPos camPrepareTarget camSetBank camSetDir camSetDive camSetFocus camSetFov camSetFovRange camSetPos camSetRelPos camSetTarget camTarget camUseNVG canAdd canAddItemToBackpack canAddItemToUniform canAddItemToVest cancelSimpleTaskDestination canFire canMove canSlingLoad canStand canSuspend canUnloadInCombat canVehicleCargo captive captiveNum cbChecked cbSetChecked ceil channelEnabled cheatsEnabled checkAIFeature checkVisibility civilian className clearAllItemsFromBackpack clearBackpackCargo clearBackpackCargoGlobal clearGroupIcons clearItemCargo clearItemCargoGlobal clearItemPool clearMagazineCargo clearMagazineCargoGlobal clearMagazinePool clearOverlay clearRadio clearWeaponCargo clearWeaponCargoGlobal clearWeaponPool clientOwner closeDialog closeDisplay closeOverlay collapseObjectTree collect3DENHistory combatMode commandArtilleryFire commandChat commander commandFire commandFollow commandFSM commandGetOut commandingMenu commandMove commandRadio commandStop commandSuppressiveFire commandTarget commandWatch comment commitOverlay compile compileFinal completedFSM composeText configClasses configFile configHierarchy configName configNull configProperties configSourceAddonList configSourceMod configSourceModList connectTerminalToUAV controlNull controlsGroupCtrl copyFromClipboard copyToClipboard copyWaypoints cos count countEnemy countFriendly countSide countType countUnknown create3DENComposition create3DENEntity createAgent createCenter createDialog createDiaryLink createDiaryRecord createDiarySubject createDisplay createGearDialog createGroup createGuardedPoint createLocation createMarker createMarkerLocal createMenu createMine createMissionDisplay createMPCampaignDisplay createSimpleObject createSimpleTask createSite createSoundSource createTask createTeam createTrigger createUnit createVehicle createVehicleCrew createVehicleLocal crew ctrlActivate ctrlAddEventHandler ctrlAngle ctrlAutoScrollDelay ctrlAutoScrollRewind ctrlAutoScrollSpeed ctrlChecked ctrlClassName ctrlCommit ctrlCommitted ctrlCreate ctrlDelete ctrlEnable ctrlEnabled ctrlFade ctrlHTMLLoaded ctrlIDC ctrlIDD ctrlMapAnimAdd ctrlMapAnimClear ctrlMapAnimCommit ctrlMapAnimDone ctrlMapCursor ctrlMapMouseOver ctrlMapScale ctrlMapScreenToWorld ctrlMapWorldToScreen ctrlModel ctrlModelDirAndUp ctrlModelScale ctrlParent ctrlParentControlsGroup ctrlPosition ctrlRemoveAllEventHandlers ctrlRemoveEventHandler ctrlScale ctrlSetActiveColor ctrlSetAngle ctrlSetAutoScrollDelay ctrlSetAutoScrollRewind ctrlSetAutoScrollSpeed ctrlSetBackgroundColor ctrlSetChecked ctrlSetEventHandler ctrlSetFade ctrlSetFocus ctrlSetFont ctrlSetFontH1 ctrlSetFontH1B ctrlSetFontH2 ctrlSetFontH2B ctrlSetFontH3 ctrlSetFontH3B ctrlSetFontH4 ctrlSetFontH4B ctrlSetFontH5 ctrlSetFontH5B ctrlSetFontH6 ctrlSetFontH6B ctrlSetFontHeight ctrlSetFontHeightH1 ctrlSetFontHeightH2 ctrlSetFontHeightH3 ctrlSetFontHeightH4 ctrlSetFontHeightH5 ctrlSetFontHeightH6 ctrlSetFontHeightSecondary ctrlSetFontP ctrlSetFontPB ctrlSetFontSecondary ctrlSetForegroundColor ctrlSetModel ctrlSetModelDirAndUp ctrlSetModelScale ctrlSetPosition ctrlSetScale ctrlSetStructuredText ctrlSetText ctrlSetTextColor ctrlSetTooltip ctrlSetTooltipColorBox ctrlSetTooltipColorShade ctrlSetTooltipColorText ctrlShow ctrlShown ctrlText ctrlTextHeight ctrlType ctrlVisible curatorAddons curatorCamera curatorCameraArea curatorCameraAreaCeiling curatorCoef curatorEditableObjects curatorEditingArea curatorEditingAreaType curatorMouseOver curatorPoints curatorRegisteredObjects curatorSelected curatorWaypointCost current3DENOperation currentChannel currentCommand currentMagazine currentMagazineDetail currentMagazineDetailTurret currentMagazineTurret currentMuzzle currentNamespace currentTask currentTasks currentThrowable currentVisionMode currentWaypoint currentWeapon currentWeaponMode currentWeaponTurret currentZeroing cursorObject cursorTarget customChat customRadio cutFadeOut cutObj cutRsc cutText damage date dateToNumber daytime deActivateKey debriefingText debugFSM debugLog deg delete3DENEntities deleteAt deleteCenter deleteCollection deleteEditorObject deleteGroup deleteIdentity deleteLocation deleteMarker deleteMarkerLocal deleteRange deleteResources deleteSite deleteStatus deleteTeam deleteVehicle deleteVehicleCrew deleteWaypoint detach detectedMines diag_activeMissionFSMs diag_activeScripts diag_activeSQFScripts diag_activeSQSScripts diag_captureFrame diag_captureSlowFrame diag_codePerformance diag_drawMode diag_enable diag_enabled diag_fps diag_fpsMin diag_frameNo diag_list diag_log diag_logSlowFrame diag_mergeConfigFile diag_recordTurretLimits diag_tickTime diag_toggle dialog diarySubjectExists didJIP didJIPOwner difficulty difficultyEnabled difficultyEnabledRTD difficultyOption direction directSay disableAI disableCollisionWith disableConversation disableDebriefingStats disableNVGEquipment disableRemoteSensors disableSerialization disableTIEquipment disableUAVConnectability disableUserInput displayAddEventHandler displayCtrl displayNull displayParent displayRemoveAllEventHandlers displayRemoveEventHandler displaySetEventHandler dissolveTeam distance distance2D distanceSqr distributionRegion do3DENAction doArtilleryFire doFire doFollow doFSM doGetOut doMove doorPhase doStop doSuppressiveFire doTarget doWatch drawArrow drawEllipse drawIcon drawIcon3D drawLine drawLine3D drawLink drawLocation drawPolygon drawRectangle driver drop east echo edit3DENMissionAttributes editObject editorSetEventHandler effectiveCommander emptyPositions enableAI enableAIFeature enableAimPrecision enableAttack enableAudioFeature enableCamShake enableCaustics enableChannel enableCollisionWith enableCopilot enableDebriefingStats enableDiagLegend enableEndDialog enableEngineArtillery enableEnvironment enableFatigue enableGunLights enableIRLasers enableMimics enablePersonTurret enableRadio enableReload enableRopeAttach enableSatNormalOnDetail enableSaving enableSentences enableSimulation enableSimulationGlobal enableStamina enableTeamSwitch enableUAVConnectability enableUAVWaypoints enableVehicleCargo endLoadingScreen endMission engineOn enginesIsOnRTD enginesRpmRTD enginesTorqueRTD entities estimatedEndServerTime estimatedTimeLeft evalObjectArgument everyBackpack everyContainer exec execEditorScript execFSM execVM exp expectedDestination exportJIPMessages eyeDirection eyePos face faction fadeMusic fadeRadio fadeSound fadeSpeech failMission fillWeaponsFromPool find findCover findDisplay findEditorObject findEmptyPosition findEmptyPositionReady findNearestEnemy finishMissionInit finite fire fireAtTarget firstBackpack flag flagOwner flagSide flagTexture fleeing floor flyInHeight flyInHeightASL fog fogForecast fogParams forceAddUniform forcedMap forceEnd forceMap forceRespawn forceSpeed forceWalk forceWeaponFire forceWeatherChange forEachMember forEachMemberAgent forEachMemberTeam format formation formationDirection formationLeader formationMembers formationPosition formationTask formatText formLeader freeLook fromEditor fuel fullCrew gearIDCAmmoCount gearSlotAmmoCount gearSlotData get3DENActionState get3DENAttribute get3DENCamera get3DENConnections get3DENEntity get3DENEntityID get3DENGrid get3DENIconsVisible get3DENLayerEntities get3DENLinesVisible get3DENMissionAttribute get3DENMouseOver get3DENSelected getAimingCoef getAllHitPointsDamage getAllOwnedMines getAmmoCargo getAnimAimPrecision getAnimSpeedCoef getArray getArtilleryAmmo getArtilleryComputerSettings getArtilleryETA getAssignedCuratorLogic getAssignedCuratorUnit getBackpackCargo getBleedingRemaining getBurningValue getCameraViewDirection getCargoIndex getCenterOfMass getClientState getClientStateNumber getConnectedUAV getCustomAimingCoef getDammage getDescription getDir getDirVisual getDLCs getEditorCamera getEditorMode getEditorObjectScope getElevationOffset getFatigue getFriend getFSMVariable getFuelCargo getGroupIcon getGroupIconParams getGroupIcons getHideFrom getHit getHitIndex getHitPointDamage getItemCargo getMagazineCargo getMarkerColor getMarkerPos getMarkerSize getMarkerType getMass getMissionConfig getMissionConfigValue getMissionDLCs getMissionLayerEntities getModelInfo getMousePosition getNumber getObjectArgument getObjectChildren getObjectDLC getObjectMaterials getObjectProxy getObjectTextures getObjectType getObjectViewDistance getOxygenRemaining getPersonUsedDLCs getPilotCameraDirection getPilotCameraPosition getPilotCameraRotation getPilotCameraTarget getPlayerChannel getPlayerScores getPlayerUID getPos getPosASL getPosASLVisual getPosASLW getPosATL getPosATLVisual getPosVisual getPosWorld getRelDir getRelPos getRemoteSensorsDisabled getRepairCargo getResolution getShadowDistance getShotParents getSlingLoad getSpeed getStamina getStatValue getSuppression getTerrainHeightASL getText getUnitLoadout getUnitTrait getVariable getVehicleCargo getWeaponCargo getWeaponSway getWPPos glanceAt globalChat globalRadio goggles goto group groupChat groupFromNetId groupIconSelectable groupIconsVisible groupId groupOwner groupRadio groupSelectedUnits groupSelectUnit grpNull gunner gusts halt handgunItems handgunMagazine handgunWeapon handsHit hasInterface hasPilotCamera hasWeapon hcAllGroups hcGroupParams hcLeader hcRemoveAllGroups hcRemoveGroup hcSelected hcSelectGroup hcSetGroup hcShowBar hcShownBar headgear hideBody hideObject hideObjectGlobal hideSelection hint hintC hintCadet hintSilent hmd hostMission htmlLoad HUDMovementLevels humidity image importAllGroups importance in inArea inAreaArray incapacitatedState independent inflame inflamed inGameUISetEventHandler inheritsFrom initAmbientLife inPolygon inputAction inRangeOfArtillery insertEditorObject intersect is3DEN is3DENMultiplayer isAbleToBreathe isAgent isArray isAutoHoverOn isAutonomous isAutotest isBleeding isBurning isClass isCollisionLightOn isCopilotEnabled isDedicated isDLCAvailable isEngineOn isEqualTo isEqualType isEqualTypeAll isEqualTypeAny isEqualTypeArray isEqualTypeParams isFilePatchingEnabled isFlashlightOn isFlatEmpty isForcedWalk isFormationLeader isHidden isInRemainsCollector isInstructorFigureEnabled isIRLaserOn isKeyActive isKindOf isLightOn isLocalized isManualFire isMarkedForCollection isMultiplayer isMultiplayerSolo isNil isNull isNumber isObjectHidden isObjectRTD isOnRoad isPipEnabled isPlayer isRealTime isRemoteExecuted isRemoteExecutedJIP isServer isShowing3DIcons isSprintAllowed isStaminaEnabled isSteamMission isStreamFriendlyUIEnabled isText isTouchingGround isTurnedOut isTutHintsEnabled isUAVConnectable isUAVConnected isUniformAllowed isVehicleCargo isWalking isWeaponDeployed isWeaponRested itemCargo items itemsWithMagazines join joinAs joinAsSilent joinSilent joinString kbAddDatabase kbAddDatabaseTargets kbAddTopic kbHasTopic kbReact kbRemoveTopic kbTell kbWasSaid keyImage keyName knowsAbout land landAt landResult language laserTarget lbAdd lbClear lbColor lbCurSel lbData lbDelete lbIsSelected lbPicture lbSelection lbSetColor lbSetCurSel lbSetData lbSetPicture lbSetPictureColor lbSetPictureColorDisabled lbSetPictureColorSelected lbSetSelectColor lbSetSelectColorRight lbSetSelected lbSetTooltip lbSetValue lbSize lbSort lbSortByValue lbText lbValue leader leaderboardDeInit leaderboardGetRows leaderboardInit leaveVehicle libraryCredits libraryDisclaimers lifeState lightAttachObject lightDetachObject lightIsOn lightnings limitSpeed linearConversion lineBreak lineIntersects lineIntersectsObjs lineIntersectsSurfaces lineIntersectsWith linkItem list listObjects ln lnbAddArray lnbAddColumn lnbAddRow lnbClear lnbColor lnbCurSelRow lnbData lnbDeleteColumn lnbDeleteRow lnbGetColumnsPosition lnbPicture lnbSetColor lnbSetColumnsPos lnbSetCurSelRow lnbSetData lnbSetPicture lnbSetText lnbSetValue lnbSize lnbText lnbValue load loadAbs loadBackpack loadFile loadGame loadIdentity loadMagazine loadOverlay loadStatus loadUniform loadVest local localize locationNull locationPosition lock lockCameraTo lockCargo lockDriver locked lockedCargo lockedDriver lockedTurret lockIdentity lockTurret lockWP log logEntities logNetwork logNetworkTerminate lookAt lookAtPos magazineCargo magazines magazinesAllTurrets magazinesAmmo magazinesAmmoCargo magazinesAmmoFull magazinesDetail magazinesDetailBackpack magazinesDetailUniform magazinesDetailVest magazinesTurret magazineTurretAmmo mapAnimAdd mapAnimClear mapAnimCommit mapAnimDone mapCenterOnCamera mapGridPosition markAsFinishedOnSteam markerAlpha markerBrush markerColor markerDir markerPos markerShape markerSize markerText markerType max members menuAction menuAdd menuChecked menuClear menuCollapse menuData menuDelete menuEnable menuEnabled menuExpand menuHover menuPicture menuSetAction menuSetCheck menuSetData menuSetPicture menuSetValue menuShortcut menuShortcutText menuSize menuSort menuText menuURL menuValue min mineActive mineDetectedBy missionConfigFile missionDifficulty missionName missionNamespace missionStart missionVersion mod modelToWorld modelToWorldVisual modParams moonIntensity moonPhase morale move move3DENCamera moveInAny moveInCargo moveInCommander moveInDriver moveInGunner moveInTurret moveObjectToEnd moveOut moveTime moveTo moveToCompleted moveToFailed musicVolume name nameSound nearEntities nearestBuilding nearestLocation nearestLocations nearestLocationWithDubbing nearestObject nearestObjects nearestTerrainObjects nearObjects nearObjectsReady nearRoads nearSupplies nearTargets needReload netId netObjNull newOverlay nextMenuItemIndex nextWeatherChange nMenuItems not numberToDate objectCurators objectFromNetId objectParent objNull objStatus onBriefingGroup onBriefingNotes onBriefingPlan onBriefingTeamSwitch onCommandModeChanged onDoubleClick onEachFrame onGroupIconClick onGroupIconOverEnter onGroupIconOverLeave onHCGroupSelectionChanged onMapSingleClick onPlayerConnected onPlayerDisconnected onPreloadFinished onPreloadStarted onShowNewObject onTeamSwitch openCuratorInterface openDLCPage openMap openYoutubeVideo opfor or orderGetIn overcast overcastForecast owner param params parseNumber parseText parsingNamespace particlesQuality pi pickWeaponPool pitch pixelGrid pixelGridBase pixelGridNoUIScale pixelH pixelW playableSlotsNumber playableUnits playAction playActionNow player playerRespawnTime playerSide playersNumber playGesture playMission playMove playMoveNow playMusic playScriptedMission playSound playSound3D position positionCameraToWorld posScreenToWorld posWorldToScreen ppEffectAdjust ppEffectCommit ppEffectCommitted ppEffectCreate ppEffectDestroy ppEffectEnable ppEffectEnabled ppEffectForceInNVG precision preloadCamera preloadObject preloadSound preloadTitleObj preloadTitleRsc preprocessFile preprocessFileLineNumbers primaryWeapon primaryWeaponItems primaryWeaponMagazine priority private processDiaryLink productVersion profileName profileNamespace profileNameSteam progressLoadingScreen progressPosition progressSetPosition publicVariable publicVariableClient publicVariableServer pushBack pushBackUnique putWeaponPool queryItemsPool queryMagazinePool queryWeaponPool rad radioChannelAdd radioChannelCreate radioChannelRemove radioChannelSetCallSign radioChannelSetLabel radioVolume rain rainbow random rank rankId rating rectangular registeredTasks registerTask reload reloadEnabled remoteControl remoteExec remoteExecCall remove3DENConnection remove3DENEventHandler remove3DENLayer removeAction removeAll3DENEventHandlers removeAllActions removeAllAssignedItems removeAllContainers removeAllCuratorAddons removeAllCuratorCameraAreas removeAllCuratorEditingAreas removeAllEventHandlers removeAllHandgunItems removeAllItems removeAllItemsWithMagazines removeAllMissionEventHandlers removeAllMPEventHandlers removeAllMusicEventHandlers removeAllOwnedMines removeAllPrimaryWeaponItems removeAllWeapons removeBackpack removeBackpackGlobal removeCuratorAddons removeCuratorCameraArea removeCuratorEditableObjects removeCuratorEditingArea removeDrawIcon removeDrawLinks removeEventHandler removeFromRemainsCollector removeGoggles removeGroupIcon removeHandgunItem removeHeadgear removeItem removeItemFromBackpack removeItemFromUniform removeItemFromVest removeItems removeMagazine removeMagazineGlobal removeMagazines removeMagazinesTurret removeMagazineTurret removeMenuItem removeMissionEventHandler removeMPEventHandler removeMusicEventHandler removeOwnedMine removePrimaryWeaponItem removeSecondaryWeaponItem removeSimpleTask removeSwitchableUnit removeTeamMember removeUniform removeVest removeWeapon removeWeaponGlobal removeWeaponTurret requiredVersion resetCamShake resetSubgroupDirection resistance resize resources respawnVehicle restartEditorCamera reveal revealMine reverse reversedMouseY roadAt roadsConnectedTo roleDescription ropeAttachedObjects ropeAttachedTo ropeAttachEnabled ropeAttachTo ropeCreate ropeCut ropeDestroy ropeDetach ropeEndPosition ropeLength ropes ropeUnwind ropeUnwound rotorsForcesRTD rotorsRpmRTD round runInitScript safeZoneH safeZoneW safeZoneWAbs safeZoneX safeZoneXAbs safeZoneY save3DENInventory saveGame saveIdentity saveJoysticks saveOverlay saveProfileNamespace saveStatus saveVar savingEnabled say say2D say3D scopeName score scoreSide screenshot screenToWorld scriptDone scriptName scriptNull scudState secondaryWeapon secondaryWeaponItems secondaryWeaponMagazine select selectBestPlaces selectDiarySubject selectedEditorObjects selectEditorObject selectionNames selectionPosition selectLeader selectMax selectMin selectNoPlayer selectPlayer selectRandom selectWeapon selectWeaponTurret sendAUMessage sendSimpleCommand sendTask sendTaskResult sendUDPMessage serverCommand serverCommandAvailable serverCommandExecutable serverName serverTime set set3DENAttribute set3DENAttributes set3DENGrid set3DENIconsVisible set3DENLayer set3DENLinesVisible set3DENMissionAttributes set3DENModelsVisible set3DENObjectType set3DENSelected setAccTime setAirportSide setAmmo setAmmoCargo setAnimSpeedCoef setAperture setApertureNew setArmoryPoints setAttributes setAutonomous setBehaviour setBleedingRemaining setCameraInterest setCamShakeDefParams setCamShakeParams setCamUseTi setCaptive setCenterOfMass setCollisionLight setCombatMode setCompassOscillation setCuratorCameraAreaCeiling setCuratorCoef setCuratorEditingAreaType setCuratorWaypointCost setCurrentChannel setCurrentTask setCurrentWaypoint setCustomAimCoef setDamage setDammage setDate setDebriefingText setDefaultCamera setDestination setDetailMapBlendPars setDir setDirection setDrawIcon setDropInterval setEditorMode setEditorObjectScope setEffectCondition setFace setFaceAnimation setFatigue setFlagOwner setFlagSide setFlagTexture setFog setFormation setFormationTask setFormDir setFriend setFromEditor setFSMVariable setFuel setFuelCargo setGroupIcon setGroupIconParams setGroupIconsSelectable setGroupIconsVisible setGroupId setGroupIdGlobal setGroupOwner setGusts setHideBehind setHit setHitIndex setHitPointDamage setHorizonParallaxCoef setHUDMovementLevels setIdentity setImportance setLeader setLightAmbient setLightAttenuation setLightBrightness setLightColor setLightDayLight setLightFlareMaxDistance setLightFlareSize setLightIntensity setLightnings setLightUseFlare setLocalWindParams setMagazineTurretAmmo setMarkerAlpha setMarkerAlphaLocal setMarkerBrush setMarkerBrushLocal setMarkerColor setMarkerColorLocal setMarkerDir setMarkerDirLocal setMarkerPos setMarkerPosLocal setMarkerShape setMarkerShapeLocal setMarkerSize setMarkerSizeLocal setMarkerText setMarkerTextLocal setMarkerType setMarkerTypeLocal setMass setMimic setMousePosition setMusicEffect setMusicEventHandler setName setNameSound setObjectArguments setObjectMaterial setObjectMaterialGlobal setObjectProxy setObjectTexture setObjectTextureGlobal setObjectViewDistance setOvercast setOwner setOxygenRemaining setParticleCircle setParticleClass setParticleFire setParticleParams setParticleRandom setPilotCameraDirection setPilotCameraRotation setPilotCameraTarget setPilotLight setPiPEffect setPitch setPlayable setPlayerRespawnTime setPos setPosASL setPosASL2 setPosASLW setPosATL setPosition setPosWorld setRadioMsg setRain setRainbow setRandomLip setRank setRectangular setRepairCargo setShadowDistance setShotParents setSide setSimpleTaskAlwaysVisible setSimpleTaskCustomData setSimpleTaskDescription setSimpleTaskDestination setSimpleTaskTarget setSimpleTaskType setSimulWeatherLayers setSize setSkill setSlingLoad setSoundEffect setSpeaker setSpeech setSpeedMode setStamina setStaminaScheme setStatValue setSuppression setSystemOfUnits setTargetAge setTaskResult setTaskState setTerrainGrid setText setTimeMultiplier setTitleEffect setTriggerActivation setTriggerArea setTriggerStatements setTriggerText setTriggerTimeout setTriggerType setType setUnconscious setUnitAbility setUnitLoadout setUnitPos setUnitPosWeak setUnitRank setUnitRecoilCoefficient setUnitTrait setUnloadInCombat setUserActionText setVariable setVectorDir setVectorDirAndUp setVectorUp setVehicleAmmo setVehicleAmmoDef setVehicleArmor setVehicleCargo setVehicleId setVehicleLock setVehiclePosition setVehicleTiPars setVehicleVarName setVelocity setVelocityTransformation setViewDistance setVisibleIfTreeCollapsed setWaves setWaypointBehaviour setWaypointCombatMode setWaypointCompletionRadius setWaypointDescription setWaypointForceBehaviour setWaypointFormation setWaypointHousePosition setWaypointLoiterRadius setWaypointLoiterType setWaypointName setWaypointPosition setWaypointScript setWaypointSpeed setWaypointStatements setWaypointTimeout setWaypointType setWaypointVisible setWeaponReloadingTime setWind setWindDir setWindForce setWindStr setWPPos show3DIcons showChat showCinemaBorder showCommandingMenu showCompass showCuratorCompass showGPS showHUD showLegend showMap shownArtilleryComputer shownChat shownCompass shownCuratorCompass showNewEditorObject shownGPS shownHUD shownMap shownPad shownRadio shownScoretable shownUAVFeed shownWarrant shownWatch showPad showRadio showScoretable showSubtitles showUAVFeed showWarrant showWatch showWaypoint showWaypoints side sideAmbientLife sideChat sideEmpty sideEnemy sideFriendly sideLogic sideRadio sideUnknown simpleTasks simulationEnabled simulCloudDensity simulCloudOcclusion simulInClouds simulWeatherSync sin size sizeOf skill skillFinal skipTime sleep sliderPosition sliderRange sliderSetPosition sliderSetRange sliderSetSpeed sliderSpeed slingLoadAssistantShown soldierMagazines someAmmo sort soundVolume spawn speaker speed speedMode splitString sqrt squadParams stance startLoadingScreen step stop stopEngineRTD stopped str sunOrMoon supportInfo suppressFor surfaceIsWater surfaceNormal surfaceType swimInDepth switchableUnits switchAction switchCamera switchGesture switchLight switchMove synchronizedObjects synchronizedTriggers synchronizedWaypoints synchronizeObjectsAdd synchronizeObjectsRemove synchronizeTrigger synchronizeWaypoint systemChat systemOfUnits tan targetKnowledge targetsAggregate targetsQuery taskAlwaysVisible taskChildren taskCompleted taskCustomData taskDescription taskDestination taskHint taskMarkerOffset taskNull taskParent taskResult taskState taskType teamMember teamMemberNull teamName teams teamSwitch teamSwitchEnabled teamType terminate terrainIntersect terrainIntersectASL text textLog textLogFormat tg time timeMultiplier titleCut titleFadeOut titleObj titleRsc titleText toArray toFixed toLower toString toUpper triggerActivated triggerActivation triggerArea triggerAttachedVehicle triggerAttachObject triggerAttachVehicle triggerStatements triggerText triggerTimeout triggerTimeoutCurrent triggerType turretLocal turretOwner turretUnit tvAdd tvClear tvCollapse tvCount tvCurSel tvData tvDelete tvExpand tvPicture tvSetCurSel tvSetData tvSetPicture tvSetPictureColor tvSetPictureColorDisabled tvSetPictureColorSelected tvSetPictureRight tvSetPictureRightColor tvSetPictureRightColorDisabled tvSetPictureRightColorSelected tvSetText tvSetTooltip tvSetValue tvSort tvSortByValue tvText tvTooltip tvValue type typeName typeOf UAVControl uiNamespace uiSleep unassignCurator unassignItem unassignTeam unassignVehicle underwater uniform uniformContainer uniformItems uniformMagazines unitAddons unitAimPosition unitAimPositionVisual unitBackpack unitIsUAV unitPos unitReady unitRecoilCoefficient units unitsBelowHeight unlinkItem unlockAchievement unregisterTask updateDrawIcon updateMenuItem updateObjectTree useAISteeringComponent useAudioTimeForMoves vectorAdd vectorCos vectorCrossProduct vectorDiff vectorDir vectorDirVisual vectorDistance vectorDistanceSqr vectorDotProduct vectorFromTo vectorMagnitude vectorMagnitudeSqr vectorMultiply vectorNormalized vectorUp vectorUpVisual vehicle vehicleCargoEnabled vehicleChat vehicleRadio vehicles vehicleVarName velocity velocityModelSpace verifySignature vest vestContainer vestItems vestMagazines viewDistance visibleCompass visibleGPS visibleMap visiblePosition visiblePositionASL visibleScoretable visibleWatch waves waypointAttachedObject waypointAttachedVehicle waypointAttachObject waypointAttachVehicle waypointBehaviour waypointCombatMode waypointCompletionRadius waypointDescription waypointForceBehaviour waypointFormation waypointHousePosition waypointLoiterRadius waypointLoiterType waypointName waypointPosition waypoints waypointScript waypointsEnabledUAV waypointShow waypointSpeed waypointStatements waypointTimeout waypointTimeoutCurrent waypointType waypointVisible weaponAccessories weaponAccessoriesCargo weaponCargo weaponDirection weaponInertia weaponLowered weapons weaponsItems weaponsItemsCargo weaponState weaponsTurret weightRTD west WFSideText wind",literal:"true false nil"},c:[e.CLCM,e.CBCM,e.NM,a,o,r,t.preprocessor],i:/#/}});hljs.registerLanguage("stan",function(e){return{c:[e.HCM,e.CLCM,e.CBCM,{b:e.UIR,l:e.UIR,k:{name:"for in while repeat until if then else",symbol:"bernoulli bernoulli_logit binomial binomial_logit beta_binomial hypergeometric categorical categorical_logit ordered_logistic neg_binomial neg_binomial_2 neg_binomial_2_log poisson poisson_log multinomial normal exp_mod_normal skew_normal student_t cauchy double_exponential logistic gumbel lognormal chi_square inv_chi_square scaled_inv_chi_square exponential inv_gamma weibull frechet rayleigh wiener pareto pareto_type_2 von_mises uniform multi_normal multi_normal_prec multi_normal_cholesky multi_gp multi_gp_cholesky multi_student_t gaussian_dlm_obs dirichlet lkj_corr lkj_corr_cholesky wishart inv_wishart","selector-tag":"int real vector simplex unit_vector ordered positive_ordered row_vector matrix cholesky_factor_corr cholesky_factor_cov corr_matrix cov_matrix",title:"functions model data parameters quantities transformed generated",literal:"true false"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",r:0},{cN:"number",b:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",r:0},{cN:"number",b:"\\d+\\.(?!\\d)(?:i\\b)?",r:0},{cN:"number",b:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",r:0}]}});hljs.registerLanguage("lua",function(e){var t="\\[=*\\[",a="\\]=*\\]",r={b:t,e:a,c:["self"]},n=[e.C("--(?!"+t+")","$"),e.C("--"+t,a,{c:[r],r:10})];return{l:e.UIR,k:{literal:"true false nil",keyword:"and break do else elseif end for goto if in local not or repeat return then until while",built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstringmodule next pairs pcall print rawequal rawget rawset require select setfenvsetmetatable tonumber tostring type unpack xpcall arg selfcoroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove"},c:n.concat([{cN:"function",bK:"function",e:"\\)",c:[e.inherit(e.TM,{b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{cN:"params",b:"\\(",eW:!0,c:n}].concat(n)},e.CNM,e.ASM,e.QSM,{cN:"string",b:t,e:a,c:[r],r:5}])}});hljs.registerLanguage("mel",function(e){return{k:"int float string vector matrix if else switch case default while do for in break continue global proc return about abs addAttr addAttributeEditorNodeHelp addDynamic addNewShelfTab addPP addPanelCategory addPrefixToName advanceToNextDrivenKey affectedNet affects aimConstraint air alias aliasAttr align alignCtx alignCurve alignSurface allViewFit ambientLight angle angleBetween animCone animCurveEditor animDisplay animView annotate appendStringArray applicationName applyAttrPreset applyTake arcLenDimContext arcLengthDimension arclen arrayMapper art3dPaintCtx artAttrCtx artAttrPaintVertexCtx artAttrSkinPaintCtx artAttrTool artBuildPaintMenu artFluidAttrCtx artPuttyCtx artSelectCtx artSetPaintCtx artUserPaintCtx assignCommand assignInputDevice assignViewportFactories attachCurve attachDeviceAttr attachSurface attrColorSliderGrp attrCompatibility attrControlGrp attrEnumOptionMenu attrEnumOptionMenuGrp attrFieldGrp attrFieldSliderGrp attrNavigationControlGrp attrPresetEditWin attributeExists attributeInfo attributeMenu attributeQuery autoKeyframe autoPlace bakeClip bakeFluidShading bakePartialHistory bakeResults bakeSimulation basename basenameEx batchRender bessel bevel bevelPlus binMembership bindSkin blend2 blendShape blendShapeEditor blendShapePanel blendTwoAttr blindDataType boneLattice boundary boxDollyCtx boxZoomCtx bufferCurve buildBookmarkMenu buildKeyframeMenu button buttonManip CBG cacheFile cacheFileCombine cacheFileMerge cacheFileTrack camera cameraView canCreateManip canvas capitalizeString catch catchQuiet ceil changeSubdivComponentDisplayLevel changeSubdivRegion channelBox character characterMap characterOutlineEditor characterize chdir checkBox checkBoxGrp checkDefaultRenderGlobals choice circle circularFillet clamp clear clearCache clip clipEditor clipEditorCurrentTimeCtx clipSchedule clipSchedulerOutliner clipTrimBefore closeCurve closeSurface cluster cmdFileOutput cmdScrollFieldExecuter cmdScrollFieldReporter cmdShell coarsenSubdivSelectionList collision color colorAtPoint colorEditor colorIndex colorIndexSliderGrp colorSliderButtonGrp colorSliderGrp columnLayout commandEcho commandLine commandPort compactHairSystem componentEditor compositingInterop computePolysetVolume condition cone confirmDialog connectAttr connectControl connectDynamic connectJoint connectionInfo constrain constrainValue constructionHistory container containsMultibyte contextInfo control convertFromOldLayers convertIffToPsd convertLightmap convertSolidTx convertTessellation convertUnit copyArray copyFlexor copyKey copySkinWeights cos cpButton cpCache cpClothSet cpCollision cpConstraint cpConvClothToMesh cpForces cpGetSolverAttr cpPanel cpProperty cpRigidCollisionFilter cpSeam cpSetEdit cpSetSolverAttr cpSolver cpSolverTypes cpTool cpUpdateClothUVs createDisplayLayer createDrawCtx createEditor createLayeredPsdFile createMotionField createNewShelf createNode createRenderLayer createSubdivRegion cross crossProduct ctxAbort ctxCompletion ctxEditMode ctxTraverse currentCtx currentTime currentTimeCtx currentUnit curve curveAddPtCtx curveCVCtx curveEPCtx curveEditorCtx curveIntersect curveMoveEPCtx curveOnSurface curveSketchCtx cutKey cycleCheck cylinder dagPose date defaultLightListCheckBox defaultNavigation defineDataServer defineVirtualDevice deformer deg_to_rad delete deleteAttr deleteShadingGroupsAndMaterials deleteShelfTab deleteUI deleteUnusedBrushes delrandstr detachCurve detachDeviceAttr detachSurface deviceEditor devicePanel dgInfo dgdirty dgeval dgtimer dimWhen directKeyCtx directionalLight dirmap dirname disable disconnectAttr disconnectJoint diskCache displacementToPoly displayAffected displayColor displayCull displayLevelOfDetail displayPref displayRGBColor displaySmoothness displayStats displayString displaySurface distanceDimContext distanceDimension doBlur dolly dollyCtx dopeSheetEditor dot dotProduct doubleProfileBirailSurface drag dragAttrContext draggerContext dropoffLocator duplicate duplicateCurve duplicateSurface dynCache dynControl dynExport dynExpression dynGlobals dynPaintEditor dynParticleCtx dynPref dynRelEdPanel dynRelEditor dynamicLoad editAttrLimits editDisplayLayerGlobals editDisplayLayerMembers editRenderLayerAdjustment editRenderLayerGlobals editRenderLayerMembers editor editorTemplate effector emit emitter enableDevice encodeString endString endsWith env equivalent equivalentTol erf error eval evalDeferred evalEcho event exactWorldBoundingBox exclusiveLightCheckBox exec executeForEachObject exists exp expression expressionEditorListen extendCurve extendSurface extrude fcheck fclose feof fflush fgetline fgetword file fileBrowserDialog fileDialog fileExtension fileInfo filetest filletCurve filter filterCurve filterExpand filterStudioImport findAllIntersections findAnimCurves findKeyframe findMenuItem findRelatedSkinCluster finder firstParentOf fitBspline flexor floatEq floatField floatFieldGrp floatScrollBar floatSlider floatSlider2 floatSliderButtonGrp floatSliderGrp floor flow fluidCacheInfo fluidEmitter fluidVoxelInfo flushUndo fmod fontDialog fopen formLayout format fprint frameLayout fread freeFormFillet frewind fromNativePath fwrite gamma gauss geometryConstraint getApplicationVersionAsFloat getAttr getClassification getDefaultBrush getFileList getFluidAttr getInputDeviceRange getMayaPanelTypes getModifiers getPanel getParticleAttr getPluginResource getenv getpid glRender glRenderEditor globalStitch gmatch goal gotoBindPose grabColor gradientControl gradientControlNoAttr graphDollyCtx graphSelectContext graphTrackCtx gravity grid gridLayout group groupObjectsByName HfAddAttractorToAS HfAssignAS HfBuildEqualMap HfBuildFurFiles HfBuildFurImages HfCancelAFR HfConnectASToHF HfCreateAttractor HfDeleteAS HfEditAS HfPerformCreateAS HfRemoveAttractorFromAS HfSelectAttached HfSelectAttractors HfUnAssignAS hardenPointCurve hardware hardwareRenderPanel headsUpDisplay headsUpMessage help helpLine hermite hide hilite hitTest hotBox hotkey hotkeyCheck hsv_to_rgb hudButton hudSlider hudSliderButton hwReflectionMap hwRender hwRenderLoad hyperGraph hyperPanel hyperShade hypot iconTextButton iconTextCheckBox iconTextRadioButton iconTextRadioCollection iconTextScrollList iconTextStaticLabel ikHandle ikHandleCtx ikHandleDisplayScale ikSolver ikSplineHandleCtx ikSystem ikSystemInfo ikfkDisplayMethod illustratorCurves image imfPlugins inheritTransform insertJoint insertJointCtx insertKeyCtx insertKnotCurve insertKnotSurface instance instanceable instancer intField intFieldGrp intScrollBar intSlider intSliderGrp interToUI internalVar intersect iprEngine isAnimCurve isConnected isDirty isParentOf isSameObject isTrue isValidObjectName isValidString isValidUiName isolateSelect itemFilter itemFilterAttr itemFilterRender itemFilterType joint jointCluster jointCtx jointDisplayScale jointLattice keyTangent keyframe keyframeOutliner keyframeRegionCurrentTimeCtx keyframeRegionDirectKeyCtx keyframeRegionDollyCtx keyframeRegionInsertKeyCtx keyframeRegionMoveKeyCtx keyframeRegionScaleKeyCtx keyframeRegionSelectKeyCtx keyframeRegionSetKeyCtx keyframeRegionTrackCtx keyframeStats lassoContext lattice latticeDeformKeyCtx launch launchImageEditor layerButton layeredShaderPort layeredTexturePort layout layoutDialog lightList lightListEditor lightListPanel lightlink lineIntersection linearPrecision linstep listAnimatable listAttr listCameras listConnections listDeviceAttachments listHistory listInputDeviceAxes listInputDeviceButtons listInputDevices listMenuAnnotation listNodeTypes listPanelCategories listRelatives listSets listTransforms listUnselected listerEditor loadFluid loadNewShelf loadPlugin loadPluginLanguageResources loadPrefObjects localizedPanelLabel lockNode loft log longNameOf lookThru ls lsThroughFilter lsType lsUI Mayatomr mag makeIdentity makeLive makePaintable makeRoll makeSingleSurface makeTubeOn makebot manipMoveContext manipMoveLimitsCtx manipOptions manipRotateContext manipRotateLimitsCtx manipScaleContext manipScaleLimitsCtx marker match max memory menu menuBarLayout menuEditor menuItem menuItemToShelf menuSet menuSetPref messageLine min minimizeApp mirrorJoint modelCurrentTimeCtx modelEditor modelPanel mouse movIn movOut move moveIKtoFK moveKeyCtx moveVertexAlongDirection multiProfileBirailSurface mute nParticle nameCommand nameField namespace namespaceInfo newPanelItems newton nodeCast nodeIconButton nodeOutliner nodePreset nodeType noise nonLinear normalConstraint normalize nurbsBoolean nurbsCopyUVSet nurbsCube nurbsEditUV nurbsPlane nurbsSelect nurbsSquare nurbsToPoly nurbsToPolygonsPref nurbsToSubdiv nurbsToSubdivPref nurbsUVSet nurbsViewDirectionVector objExists objectCenter objectLayer objectType objectTypeUI obsoleteProc oceanNurbsPreviewPlane offsetCurve offsetCurveOnSurface offsetSurface openGLExtension openMayaPref optionMenu optionMenuGrp optionVar orbit orbitCtx orientConstraint outlinerEditor outlinerPanel overrideModifier paintEffectsDisplay pairBlend palettePort paneLayout panel panelConfiguration panelHistory paramDimContext paramDimension paramLocator parent parentConstraint particle particleExists particleInstancer particleRenderInfo partition pasteKey pathAnimation pause pclose percent performanceOptions pfxstrokes pickWalk picture pixelMove planarSrf plane play playbackOptions playblast plugAttr plugNode pluginInfo pluginResourceUtil pointConstraint pointCurveConstraint pointLight pointMatrixMult pointOnCurve pointOnSurface pointPosition poleVectorConstraint polyAppend polyAppendFacetCtx polyAppendVertex polyAutoProjection polyAverageNormal polyAverageVertex polyBevel polyBlendColor polyBlindData polyBoolOp polyBridgeEdge polyCacheMonitor polyCheck polyChipOff polyClipboard polyCloseBorder polyCollapseEdge polyCollapseFacet polyColorBlindData polyColorDel polyColorPerVertex polyColorSet polyCompare polyCone polyCopyUV polyCrease polyCreaseCtx polyCreateFacet polyCreateFacetCtx polyCube polyCut polyCutCtx polyCylinder polyCylindricalProjection polyDelEdge polyDelFacet polyDelVertex polyDuplicateAndConnect polyDuplicateEdge polyEditUV polyEditUVShell polyEvaluate polyExtrudeEdge polyExtrudeFacet polyExtrudeVertex polyFlipEdge polyFlipUV polyForceUV polyGeoSampler polyHelix polyInfo polyInstallAction polyLayoutUV polyListComponentConversion polyMapCut polyMapDel polyMapSew polyMapSewMove polyMergeEdge polyMergeEdgeCtx polyMergeFacet polyMergeFacetCtx polyMergeUV polyMergeVertex polyMirrorFace polyMoveEdge polyMoveFacet polyMoveFacetUV polyMoveUV polyMoveVertex polyNormal polyNormalPerVertex polyNormalizeUV polyOptUvs polyOptions polyOutput polyPipe polyPlanarProjection polyPlane polyPlatonicSolid polyPoke polyPrimitive polyPrism polyProjection polyPyramid polyQuad polyQueryBlindData polyReduce polySelect polySelectConstraint polySelectConstraintMonitor polySelectCtx polySelectEditCtx polySeparate polySetToFaceNormal polySewEdge polyShortestPathCtx polySmooth polySoftEdge polySphere polySphericalProjection polySplit polySplitCtx polySplitEdge polySplitRing polySplitVertex polyStraightenUVBorder polySubdivideEdge polySubdivideFacet polyToSubdiv polyTorus polyTransfer polyTriangulate polyUVSet polyUnite polyWedgeFace popen popupMenu pose pow preloadRefEd print progressBar progressWindow projFileViewer projectCurve projectTangent projectionContext projectionManip promptDialog propModCtx propMove psdChannelOutliner psdEditTextureFile psdExport psdTextureFile putenv pwd python querySubdiv quit rad_to_deg radial radioButton radioButtonGrp radioCollection radioMenuItemCollection rampColorPort rand randomizeFollicles randstate rangeControl readTake rebuildCurve rebuildSurface recordAttr recordDevice redo reference referenceEdit referenceQuery refineSubdivSelectionList refresh refreshAE registerPluginResource rehash reloadImage removeJoint removeMultiInstance removePanelCategory rename renameAttr renameSelectionList renameUI render renderGlobalsNode renderInfo renderLayerButton renderLayerParent renderLayerPostProcess renderLayerUnparent renderManip renderPartition renderQualityNode renderSettings renderThumbnailUpdate renderWindowEditor renderWindowSelectContext renderer reorder reorderDeformers requires reroot resampleFluid resetAE resetPfxToPolyCamera resetTool resolutionNode retarget reverseCurve reverseSurface revolve rgb_to_hsv rigidBody rigidSolver roll rollCtx rootOf rot rotate rotationInterpolation roundConstantRadius rowColumnLayout rowLayout runTimeCommand runup sampleImage saveAllShelves saveAttrPreset saveFluid saveImage saveInitialState saveMenu savePrefObjects savePrefs saveShelf saveToolSettings scale scaleBrushBrightness scaleComponents scaleConstraint scaleKey scaleKeyCtx sceneEditor sceneUIReplacement scmh scriptCtx scriptEditorInfo scriptJob scriptNode scriptTable scriptToShelf scriptedPanel scriptedPanelType scrollField scrollLayout sculpt searchPathArray seed selLoadSettings select selectContext selectCurveCV selectKey selectKeyCtx selectKeyframeRegionCtx selectMode selectPref selectPriority selectType selectedNodes selectionConnection separator setAttr setAttrEnumResource setAttrMapping setAttrNiceNameResource setConstraintRestPosition setDefaultShadingGroup setDrivenKeyframe setDynamic setEditCtx setEditor setFluidAttr setFocus setInfinity setInputDeviceMapping setKeyCtx setKeyPath setKeyframe setKeyframeBlendshapeTargetWts setMenuMode setNodeNiceNameResource setNodeTypeFlag setParent setParticleAttr setPfxToPolyCamera setPluginResource setProject setStampDensity setStartupMessage setState setToolTo setUITemplate setXformManip sets shadingConnection shadingGeometryRelCtx shadingLightRelCtx shadingNetworkCompare shadingNode shapeCompare shelfButton shelfLayout shelfTabLayout shellField shortNameOf showHelp showHidden showManipCtx showSelectionInTitle showShadingGroupAttrEditor showWindow sign simplify sin singleProfileBirailSurface size sizeBytes skinCluster skinPercent smoothCurve smoothTangentSurface smoothstep snap2to2 snapKey snapMode snapTogetherCtx snapshot soft softMod softModCtx sort sound soundControl source spaceLocator sphere sphrand spotLight spotLightPreviewPort spreadSheetEditor spring sqrt squareSurface srtContext stackTrace startString startsWith stitchAndExplodeShell stitchSurface stitchSurfacePoints strcmp stringArrayCatenate stringArrayContains stringArrayCount stringArrayInsertAtIndex stringArrayIntersector stringArrayRemove stringArrayRemoveAtIndex stringArrayRemoveDuplicates stringArrayRemoveExact stringArrayToString stringToStringArray strip stripPrefixFromName stroke subdAutoProjection subdCleanTopology subdCollapse subdDuplicateAndConnect subdEditUV subdListComponentConversion subdMapCut subdMapSewMove subdMatchTopology subdMirror subdToBlind subdToPoly subdTransferUVsToCache subdiv subdivCrease subdivDisplaySmoothness substitute substituteAllString substituteGeometry substring surface surfaceSampler surfaceShaderList swatchDisplayPort switchTable symbolButton symbolCheckBox sysFile system tabLayout tan tangentConstraint texLatticeDeformContext texManipContext texMoveContext texMoveUVShellContext texRotateContext texScaleContext texSelectContext texSelectShortestPathCtx texSmudgeUVContext texWinToolCtx text textCurves textField textFieldButtonGrp textFieldGrp textManip textScrollList textToShelf textureDisplacePlane textureHairColor texturePlacementContext textureWindow threadCount threePointArcCtx timeControl timePort timerX toNativePath toggle toggleAxis toggleWindowVisibility tokenize tokenizeList tolerance tolower toolButton toolCollection toolDropped toolHasOptions toolPropertyWindow torus toupper trace track trackCtx transferAttributes transformCompare transformLimits translator trim trunc truncateFluidCache truncateHairCache tumble tumbleCtx turbulence twoPointArcCtx uiRes uiTemplate unassignInputDevice undo undoInfo ungroup uniform unit unloadPlugin untangleUV untitledFileName untrim upAxis updateAE userCtx uvLink uvSnapshot validateShelfName vectorize view2dToolCtx viewCamera viewClipPlane viewFit viewHeadOn viewLookAt viewManip viewPlace viewSet visor volumeAxis vortex waitCursor warning webBrowser webBrowserPrefs whatIs window windowPref wire wireContext workspace wrinkle wrinkleContext writeTake xbmLangPathList xform",i:" ",r:10},e.C("%","$"),{cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},e.ASM,e.QSM,{b:"\\?(::)?([A-Z]\\w*(::)?)+"},{b:"->"},{b:"ok"},{b:"!"},{b:"(\\b[a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*)|(\\b[a-z'][a-zA-Z0-9_']*)",r:0},{b:"[A-Z][a-zA-Z0-9_']*",r:0}]}});hljs.registerLanguage("dsconfig",function(e){var i={cN:"string",b:/"/,e:/"/},r={cN:"string",b:/'/,e:/'/},s={cN:"string",b:"[\\w-?]+:\\w+",e:"\\W",r:0},t={cN:"string",b:"\\w+-?\\w+",e:"\\W",r:0};return{k:"dsconfig",c:[{cN:"keyword",b:"^dsconfig",e:"\\s",eE:!0,r:10},{cN:"built_in",b:"(list|create|get|set|delete)-(\\w+)",e:"\\s",eE:!0,i:"!@#$%^&*()",r:10},{cN:"built_in",b:"--(\\w+)",e:"\\s",eE:!0},i,r,s,t,e.HCM]}});hljs.registerLanguage("pf",function(t){var o={cN:"variable",b:/\$[\w\d#@][\w\d_]*/},e={cN:"variable",b:/<(?!\/)/,e:/>/};return{aliases:["pf.conf"],l:/[a-z0-9_<>-]+/,k:{built_in:"block match pass load anchor|5 antispoof|10 set table",keyword:"in out log quick on rdomain inet inet6 proto from port os to routeallow-opts divert-packet divert-reply divert-to flags group icmp-typeicmp6-type label once probability recieved-on rtable prio queuetos tag tagged user keep fragment for os dropaf-to|10 binat-to|10 nat-to|10 rdr-to|10 bitmask least-stats random round-robinsource-hash static-portdup-to reply-to route-toparent bandwidth default min max qlimitblock-policy debug fingerprints hostid limit loginterface optimizationreassemble ruleset-optimization basic none profile skip state-defaultsstate-policy timeoutconst counters persistno modulate synproxy state|5 floating if-bound no-sync pflow|10 sloppysource-track global rule max-src-nodes max-src-states max-src-connmax-src-conn-rate overload flushscrub|5 max-mss min-ttl no-df|10 random-id",literal:"all any no-route self urpf-failed egress|5 unknown"},c:[t.HCM,t.NM,t.QSM,o,e]}});hljs.registerLanguage("x86asm",function(s){return{cI:!0,l:"[.%]?"+s.IR,k:{keyword:"lock rep repe repz repne repnz xaquire xrelease bnd nobnd aaa aad aam aas adc add and arpl bb0_reset bb1_reset bound bsf bsr bswap bt btc btr bts call cbw cdq cdqe clc cld cli clts cmc cmp cmpsb cmpsd cmpsq cmpsw cmpxchg cmpxchg486 cmpxchg8b cmpxchg16b cpuid cpu_read cpu_write cqo cwd cwde daa das dec div dmint emms enter equ f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem fprem1 fptan frndint frstor fsave fscale fsetpm fsin fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr fsubrp ftst fucom fucomi fucomip fucomp fucompp fxam fxch fxtract fyl2x fyl2xp1 hlt ibts icebp idiv imul in inc incbin insb insd insw int int01 int1 int03 int3 into invd invpcid invlpg invlpga iret iretd iretq iretw jcxz jecxz jrcxz jmp jmpe lahf lar lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw loadall loadall286 lodsb lodsd lodsq lodsw loop loope loopne loopnz loopz lsl lss ltr mfence monitor mov movd movq movsb movsd movsq movsw movsx movsxd movzx mul mwait neg nop not or out outsb outsd outsw packssdw packsswb packuswb paddb paddd paddsb paddsiw paddsw paddusb paddusw paddw pand pandn pause paveb pavgusb pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pdistib pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmachriw pmaddwd pmagw pmulhriw pmulhrwa pmulhrwc pmulhw pmullw pmvgezb pmvlzb pmvnzb pmvzb pop popa popad popaw popf popfd popfq popfw por prefetch prefetchw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb psubd psubsb psubsiw psubsw psubusb psubusw psubw punpckhbw punpckhdq punpckhwd punpcklbw punpckldq punpcklwd push pusha pushad pushaw pushf pushfd pushfq pushfw pxor rcl rcr rdshr rdmsr rdpmc rdtsc rdtscp ret retf retn rol ror rdm rsdc rsldt rsm rsts sahf sal salc sar sbb scasb scasd scasq scasw sfence sgdt shl shld shr shrd sidt sldt skinit smi smint smintold smsw stc std sti stosb stosd stosq stosw str sub svdc svldt svts swapgs syscall sysenter sysexit sysret test ud0 ud1 ud2b ud2 ud2a umov verr verw fwait wbinvd wrshr wrmsr xadd xbts xchg xlatb xlat xor cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp sete setz setne setnz seta setnbe setae setnb setnc setb setnae setcset setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp addps addss andnps andps cmpeqps cmpeqss cmpleps cmpless cmpltps cmpltss cmpneqps cmpneqss cmpnleps cmpnless cmpnltps cmpnltss cmpordps cmpordss cmpunordps cmpunordss cmpps cmpss comiss cvtpi2ps cvtps2pi cvtsi2ss cvtss2si cvttps2pi cvttss2si divps divss ldmxcsr maxps maxss minps minss movaps movhps movlhps movlps movhlps movmskps movntps movss movups mulps mulss orps rcpps rcpss rsqrtps rsqrtss shufps sqrtps sqrtss stmxcsr subps subss ucomiss unpckhps unpcklps xorps fxrstor fxrstor64 fxsave fxsave64 xgetbv xsetbv xsave xsave64 xsaveopt xsaveopt64 xrstor xrstor64 prefetchnta prefetcht0 prefetcht1 prefetcht2 maskmovq movntq pavgb pavgw pextrw pinsrw pmaxsw pmaxub pminsw pminub pmovmskb pmulhuw psadbw pshufw pf2iw pfnacc pfpnacc pi2fw pswapd maskmovdqu clflush movntdq movnti movntpd movdqa movdqu movdq2q movq2dq paddq pmuludq pshufd pshufhw pshuflw pslldq psrldq psubq punpckhqdq punpcklqdq addpd addsd andnpd andpd cmpeqpd cmpeqsd cmplepd cmplesd cmpltpd cmpltsd cmpneqpd cmpneqsd cmpnlepd cmpnlesd cmpnltpd cmpnltsd cmpordpd cmpordsd cmpunordpd cmpunordsd cmppd comisd cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtps2dq cvtps2pd cvtsd2si cvtsd2ss cvtsi2sd cvtss2sd cvttpd2pi cvttpd2dq cvttps2dq cvttsd2si divpd divsd maxpd maxsd minpd minsd movapd movhpd movlpd movmskpd movupd mulpd mulsd orpd shufpd sqrtpd sqrtsd subpd subsd ucomisd unpckhpd unpcklpd xorpd addsubpd addsubps haddpd haddps hsubpd hsubps lddqu movddup movshdup movsldup clgi stgi vmcall vmclear vmfunc vmlaunch vmload vmmcall vmptrld vmptrst vmread vmresume vmrun vmsave vmwrite vmxoff vmxon invept invvpid pabsb pabsw pabsd palignr phaddw phaddd phaddsw phsubw phsubd phsubsw pmaddubsw pmulhrsw pshufb psignb psignw psignd extrq insertq movntsd movntss lzcnt blendpd blendps blendvpd blendvps dppd dpps extractps insertps movntdqa mpsadbw packusdw pblendvb pblendw pcmpeqq pextrb pextrd pextrq phminposuw pinsrb pinsrd pinsrq pmaxsb pmaxsd pmaxud pmaxuw pminsb pminsd pminud pminuw pmovsxbw pmovsxbd pmovsxbq pmovsxwd pmovsxwq pmovsxdq pmovzxbw pmovzxbd pmovzxbq pmovzxwd pmovzxwq pmovzxdq pmuldq pmulld ptest roundpd roundps roundsd roundss crc32 pcmpestri pcmpestrm pcmpistri pcmpistrm pcmpgtq popcnt getsec pfrcpv pfrsqrtv movbe aesenc aesenclast aesdec aesdeclast aesimc aeskeygenassist vaesenc vaesenclast vaesdec vaesdeclast vaesimc vaeskeygenassist vaddpd vaddps vaddsd vaddss vaddsubpd vaddsubps vandpd vandps vandnpd vandnps vblendpd vblendps vblendvpd vblendvps vbroadcastss vbroadcastsd vbroadcastf128 vcmpeq_ospd vcmpeqpd vcmplt_ospd vcmpltpd vcmple_ospd vcmplepd vcmpunord_qpd vcmpunordpd vcmpneq_uqpd vcmpneqpd vcmpnlt_uspd vcmpnltpd vcmpnle_uspd vcmpnlepd vcmpord_qpd vcmpordpd vcmpeq_uqpd vcmpnge_uspd vcmpngepd vcmpngt_uspd vcmpngtpd vcmpfalse_oqpd vcmpfalsepd vcmpneq_oqpd vcmpge_ospd vcmpgepd vcmpgt_ospd vcmpgtpd vcmptrue_uqpd vcmptruepd vcmplt_oqpd vcmple_oqpd vcmpunord_spd vcmpneq_uspd vcmpnlt_uqpd vcmpnle_uqpd vcmpord_spd vcmpeq_uspd vcmpnge_uqpd vcmpngt_uqpd vcmpfalse_ospd vcmpneq_ospd vcmpge_oqpd vcmpgt_oqpd vcmptrue_uspd vcmppd vcmpeq_osps vcmpeqps vcmplt_osps vcmpltps vcmple_osps vcmpleps vcmpunord_qps vcmpunordps vcmpneq_uqps vcmpneqps vcmpnlt_usps vcmpnltps vcmpnle_usps vcmpnleps vcmpord_qps vcmpordps vcmpeq_uqps vcmpnge_usps vcmpngeps vcmpngt_usps vcmpngtps vcmpfalse_oqps vcmpfalseps vcmpneq_oqps vcmpge_osps vcmpgeps vcmpgt_osps vcmpgtps vcmptrue_uqps vcmptrueps vcmplt_oqps vcmple_oqps vcmpunord_sps vcmpneq_usps vcmpnlt_uqps vcmpnle_uqps vcmpord_sps vcmpeq_usps vcmpnge_uqps vcmpngt_uqps vcmpfalse_osps vcmpneq_osps vcmpge_oqps vcmpgt_oqps vcmptrue_usps vcmpps vcmpeq_ossd vcmpeqsd vcmplt_ossd vcmpltsd vcmple_ossd vcmplesd vcmpunord_qsd vcmpunordsd vcmpneq_uqsd vcmpneqsd vcmpnlt_ussd vcmpnltsd vcmpnle_ussd vcmpnlesd vcmpord_qsd vcmpordsd vcmpeq_uqsd vcmpnge_ussd vcmpngesd vcmpngt_ussd vcmpngtsd vcmpfalse_oqsd vcmpfalsesd vcmpneq_oqsd vcmpge_ossd vcmpgesd vcmpgt_ossd vcmpgtsd vcmptrue_uqsd vcmptruesd vcmplt_oqsd vcmple_oqsd vcmpunord_ssd vcmpneq_ussd vcmpnlt_uqsd vcmpnle_uqsd vcmpord_ssd vcmpeq_ussd vcmpnge_uqsd vcmpngt_uqsd vcmpfalse_ossd vcmpneq_ossd vcmpge_oqsd vcmpgt_oqsd vcmptrue_ussd vcmpsd vcmpeq_osss vcmpeqss vcmplt_osss vcmpltss vcmple_osss vcmpless vcmpunord_qss vcmpunordss vcmpneq_uqss vcmpneqss vcmpnlt_usss vcmpnltss vcmpnle_usss vcmpnless vcmpord_qss vcmpordss vcmpeq_uqss vcmpnge_usss vcmpngess vcmpngt_usss vcmpngtss vcmpfalse_oqss vcmpfalsess vcmpneq_oqss vcmpge_osss vcmpgess vcmpgt_osss vcmpgtss vcmptrue_uqss vcmptruess vcmplt_oqss vcmple_oqss vcmpunord_sss vcmpneq_usss vcmpnlt_uqss vcmpnle_uqss vcmpord_sss vcmpeq_usss vcmpnge_uqss vcmpngt_uqss vcmpfalse_osss vcmpneq_osss vcmpge_oqss vcmpgt_oqss vcmptrue_usss vcmpss vcomisd vcomiss vcvtdq2pd vcvtdq2ps vcvtpd2dq vcvtpd2ps vcvtps2dq vcvtps2pd vcvtsd2si vcvtsd2ss vcvtsi2sd vcvtsi2ss vcvtss2sd vcvtss2si vcvttpd2dq vcvttps2dq vcvttsd2si vcvttss2si vdivpd vdivps vdivsd vdivss vdppd vdpps vextractf128 vextractps vhaddpd vhaddps vhsubpd vhsubps vinsertf128 vinsertps vlddqu vldqqu vldmxcsr vmaskmovdqu vmaskmovps vmaskmovpd vmaxpd vmaxps vmaxsd vmaxss vminpd vminps vminsd vminss vmovapd vmovaps vmovd vmovq vmovddup vmovdqa vmovqqa vmovdqu vmovqqu vmovhlps vmovhpd vmovhps vmovlhps vmovlpd vmovlps vmovmskpd vmovmskps vmovntdq vmovntqq vmovntdqa vmovntpd vmovntps vmovsd vmovshdup vmovsldup vmovss vmovupd vmovups vmpsadbw vmulpd vmulps vmulsd vmulss vorpd vorps vpabsb vpabsw vpabsd vpacksswb vpackssdw vpackuswb vpackusdw vpaddb vpaddw vpaddd vpaddq vpaddsb vpaddsw vpaddusb vpaddusw vpalignr vpand vpandn vpavgb vpavgw vpblendvb vpblendw vpcmpestri vpcmpestrm vpcmpistri vpcmpistrm vpcmpeqb vpcmpeqw vpcmpeqd vpcmpeqq vpcmpgtb vpcmpgtw vpcmpgtd vpcmpgtq vpermilpd vpermilps vperm2f128 vpextrb vpextrw vpextrd vpextrq vphaddw vphaddd vphaddsw vphminposuw vphsubw vphsubd vphsubsw vpinsrb vpinsrw vpinsrd vpinsrq vpmaddwd vpmaddubsw vpmaxsb vpmaxsw vpmaxsd vpmaxub vpmaxuw vpmaxud vpminsb vpminsw vpminsd vpminub vpminuw vpminud vpmovmskb vpmovsxbw vpmovsxbd vpmovsxbq vpmovsxwd vpmovsxwq vpmovsxdq vpmovzxbw vpmovzxbd vpmovzxbq vpmovzxwd vpmovzxwq vpmovzxdq vpmulhuw vpmulhrsw vpmulhw vpmullw vpmulld vpmuludq vpmuldq vpor vpsadbw vpshufb vpshufd vpshufhw vpshuflw vpsignb vpsignw vpsignd vpslldq vpsrldq vpsllw vpslld vpsllq vpsraw vpsrad vpsrlw vpsrld vpsrlq vptest vpsubb vpsubw vpsubd vpsubq vpsubsb vpsubsw vpsubusb vpsubusw vpunpckhbw vpunpckhwd vpunpckhdq vpunpckhqdq vpunpcklbw vpunpcklwd vpunpckldq vpunpcklqdq vpxor vrcpps vrcpss vrsqrtps vrsqrtss vroundpd vroundps vroundsd vroundss vshufpd vshufps vsqrtpd vsqrtps vsqrtsd vsqrtss vstmxcsr vsubpd vsubps vsubsd vsubss vtestps vtestpd vucomisd vucomiss vunpckhpd vunpckhps vunpcklpd vunpcklps vxorpd vxorps vzeroall vzeroupper pclmullqlqdq pclmulhqlqdq pclmullqhqdq pclmulhqhqdq pclmulqdq vpclmullqlqdq vpclmulhqlqdq vpclmullqhqdq vpclmulhqhqdq vpclmulqdq vfmadd132ps vfmadd132pd vfmadd312ps vfmadd312pd vfmadd213ps vfmadd213pd vfmadd123ps vfmadd123pd vfmadd231ps vfmadd231pd vfmadd321ps vfmadd321pd vfmaddsub132ps vfmaddsub132pd vfmaddsub312ps vfmaddsub312pd vfmaddsub213ps vfmaddsub213pd vfmaddsub123ps vfmaddsub123pd vfmaddsub231ps vfmaddsub231pd vfmaddsub321ps vfmaddsub321pd vfmsub132ps vfmsub132pd vfmsub312ps vfmsub312pd vfmsub213ps vfmsub213pd vfmsub123ps vfmsub123pd vfmsub231ps vfmsub231pd vfmsub321ps vfmsub321pd vfmsubadd132ps vfmsubadd132pd vfmsubadd312ps vfmsubadd312pd vfmsubadd213ps vfmsubadd213pd vfmsubadd123ps vfmsubadd123pd vfmsubadd231ps vfmsubadd231pd vfmsubadd321ps vfmsubadd321pd vfnmadd132ps vfnmadd132pd vfnmadd312ps vfnmadd312pd vfnmadd213ps vfnmadd213pd vfnmadd123ps vfnmadd123pd vfnmadd231ps vfnmadd231pd vfnmadd321ps vfnmadd321pd vfnmsub132ps vfnmsub132pd vfnmsub312ps vfnmsub312pd vfnmsub213ps vfnmsub213pd vfnmsub123ps vfnmsub123pd vfnmsub231ps vfnmsub231pd vfnmsub321ps vfnmsub321pd vfmadd132ss vfmadd132sd vfmadd312ss vfmadd312sd vfmadd213ss vfmadd213sd vfmadd123ss vfmadd123sd vfmadd231ss vfmadd231sd vfmadd321ss vfmadd321sd vfmsub132ss vfmsub132sd vfmsub312ss vfmsub312sd vfmsub213ss vfmsub213sd vfmsub123ss vfmsub123sd vfmsub231ss vfmsub231sd vfmsub321ss vfmsub321sd vfnmadd132ss vfnmadd132sd vfnmadd312ss vfnmadd312sd vfnmadd213ss vfnmadd213sd vfnmadd123ss vfnmadd123sd vfnmadd231ss vfnmadd231sd vfnmadd321ss vfnmadd321sd vfnmsub132ss vfnmsub132sd vfnmsub312ss vfnmsub312sd vfnmsub213ss vfnmsub213sd vfnmsub123ss vfnmsub123sd vfnmsub231ss vfnmsub231sd vfnmsub321ss vfnmsub321sd rdfsbase rdgsbase rdrand wrfsbase wrgsbase vcvtph2ps vcvtps2ph adcx adox rdseed clac stac xstore xcryptecb xcryptcbc xcryptctr xcryptcfb xcryptofb montmul xsha1 xsha256 llwpcb slwpcb lwpval lwpins vfmaddpd vfmaddps vfmaddsd vfmaddss vfmaddsubpd vfmaddsubps vfmsubaddpd vfmsubaddps vfmsubpd vfmsubps vfmsubsd vfmsubss vfnmaddpd vfnmaddps vfnmaddsd vfnmaddss vfnmsubpd vfnmsubps vfnmsubsd vfnmsubss vfrczpd vfrczps vfrczsd vfrczss vpcmov vpcomb vpcomd vpcomq vpcomub vpcomud vpcomuq vpcomuw vpcomw vphaddbd vphaddbq vphaddbw vphadddq vphaddubd vphaddubq vphaddubw vphaddudq vphadduwd vphadduwq vphaddwd vphaddwq vphsubbw vphsubdq vphsubwd vpmacsdd vpmacsdqh vpmacsdql vpmacssdd vpmacssdqh vpmacssdql vpmacsswd vpmacssww vpmacswd vpmacsww vpmadcsswd vpmadcswd vpperm vprotb vprotd vprotq vprotw vpshab vpshad vpshaq vpshaw vpshlb vpshld vpshlq vpshlw vbroadcasti128 vpblendd vpbroadcastb vpbroadcastw vpbroadcastd vpbroadcastq vpermd vpermpd vpermps vpermq vperm2i128 vextracti128 vinserti128 vpmaskmovd vpmaskmovq vpsllvd vpsllvq vpsravd vpsrlvd vpsrlvq vgatherdpd vgatherqpd vgatherdps vgatherqps vpgatherdd vpgatherqd vpgatherdq vpgatherqq xabort xbegin xend xtest andn bextr blci blcic blsi blsic blcfill blsfill blcmsk blsmsk blsr blcs bzhi mulx pdep pext rorx sarx shlx shrx tzcnt tzmsk t1mskc valignd valignq vblendmpd vblendmps vbroadcastf32x4 vbroadcastf64x4 vbroadcasti32x4 vbroadcasti64x4 vcompresspd vcompressps vcvtpd2udq vcvtps2udq vcvtsd2usi vcvtss2usi vcvttpd2udq vcvttps2udq vcvttsd2usi vcvttss2usi vcvtudq2pd vcvtudq2ps vcvtusi2sd vcvtusi2ss vexpandpd vexpandps vextractf32x4 vextractf64x4 vextracti32x4 vextracti64x4 vfixupimmpd vfixupimmps vfixupimmsd vfixupimmss vgetexppd vgetexpps vgetexpsd vgetexpss vgetmantpd vgetmantps vgetmantsd vgetmantss vinsertf32x4 vinsertf64x4 vinserti32x4 vinserti64x4 vmovdqa32 vmovdqa64 vmovdqu32 vmovdqu64 vpabsq vpandd vpandnd vpandnq vpandq vpblendmd vpblendmq vpcmpltd vpcmpled vpcmpneqd vpcmpnltd vpcmpnled vpcmpd vpcmpltq vpcmpleq vpcmpneqq vpcmpnltq vpcmpnleq vpcmpq vpcmpequd vpcmpltud vpcmpleud vpcmpnequd vpcmpnltud vpcmpnleud vpcmpud vpcmpequq vpcmpltuq vpcmpleuq vpcmpnequq vpcmpnltuq vpcmpnleuq vpcmpuq vpcompressd vpcompressq vpermi2d vpermi2pd vpermi2ps vpermi2q vpermt2d vpermt2pd vpermt2ps vpermt2q vpexpandd vpexpandq vpmaxsq vpmaxuq vpminsq vpminuq vpmovdb vpmovdw vpmovqb vpmovqd vpmovqw vpmovsdb vpmovsdw vpmovsqb vpmovsqd vpmovsqw vpmovusdb vpmovusdw vpmovusqb vpmovusqd vpmovusqw vpord vporq vprold vprolq vprolvd vprolvq vprord vprorq vprorvd vprorvq vpscatterdd vpscatterdq vpscatterqd vpscatterqq vpsraq vpsravq vpternlogd vpternlogq vptestmd vptestmq vptestnmd vptestnmq vpxord vpxorq vrcp14pd vrcp14ps vrcp14sd vrcp14ss vrndscalepd vrndscaleps vrndscalesd vrndscaless vrsqrt14pd vrsqrt14ps vrsqrt14sd vrsqrt14ss vscalefpd vscalefps vscalefsd vscalefss vscatterdpd vscatterdps vscatterqpd vscatterqps vshuff32x4 vshuff64x2 vshufi32x4 vshufi64x2 kandnw kandw kmovw knotw kortestw korw kshiftlw kshiftrw kunpckbw kxnorw kxorw vpbroadcastmb2q vpbroadcastmw2d vpconflictd vpconflictq vplzcntd vplzcntq vexp2pd vexp2ps vrcp28pd vrcp28ps vrcp28sd vrcp28ss vrsqrt28pd vrsqrt28ps vrsqrt28sd vrsqrt28ss vgatherpf0dpd vgatherpf0dps vgatherpf0qpd vgatherpf0qps vgatherpf1dpd vgatherpf1dps vgatherpf1qpd vgatherpf1qps vscatterpf0dpd vscatterpf0dps vscatterpf0qpd vscatterpf0qps vscatterpf1dpd vscatterpf1dps vscatterpf1qpd vscatterpf1qps prefetchwt1 bndmk bndcl bndcu bndcn bndmov bndldx bndstx sha1rnds4 sha1nexte sha1msg1 sha1msg2 sha256rnds2 sha256msg1 sha256msg2 hint_nop0 hint_nop1 hint_nop2 hint_nop3 hint_nop4 hint_nop5 hint_nop6 hint_nop7 hint_nop8 hint_nop9 hint_nop10 hint_nop11 hint_nop12 hint_nop13 hint_nop14 hint_nop15 hint_nop16 hint_nop17 hint_nop18 hint_nop19 hint_nop20 hint_nop21 hint_nop22 hint_nop23 hint_nop24 hint_nop25 hint_nop26 hint_nop27 hint_nop28 hint_nop29 hint_nop30 hint_nop31 hint_nop32 hint_nop33 hint_nop34 hint_nop35 hint_nop36 hint_nop37 hint_nop38 hint_nop39 hint_nop40 hint_nop41 hint_nop42 hint_nop43 hint_nop44 hint_nop45 hint_nop46 hint_nop47 hint_nop48 hint_nop49 hint_nop50 hint_nop51 hint_nop52 hint_nop53 hint_nop54 hint_nop55 hint_nop56 hint_nop57 hint_nop58 hint_nop59 hint_nop60 hint_nop61 hint_nop62 hint_nop63",built_in:"ip eip rip al ah bl bh cl ch dl dh sil dil bpl spl r8b r9b r10b r11b r12b r13b r14b r15b ax bx cx dx si di bp sp r8w r9w r10w r11w r12w r13w r14w r15w eax ebx ecx edx esi edi ebp esp eip r8d r9d r10d r11d r12d r13d r14d r15d rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 cs ds es fs gs ss st st0 st1 st2 st3 st4 st5 st6 st7 mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15 xmm16 xmm17 xmm18 xmm19 xmm20 xmm21 xmm22 xmm23 xmm24 xmm25 xmm26 xmm27 xmm28 xmm29 xmm30 xmm31 ymm0 ymm1 ymm2 ymm3 ymm4 ymm5 ymm6 ymm7 ymm8 ymm9 ymm10 ymm11 ymm12 ymm13 ymm14 ymm15 ymm16 ymm17 ymm18 ymm19 ymm20 ymm21 ymm22 ymm23 ymm24 ymm25 ymm26 ymm27 ymm28 ymm29 ymm30 ymm31 zmm0 zmm1 zmm2 zmm3 zmm4 zmm5 zmm6 zmm7 zmm8 zmm9 zmm10 zmm11 zmm12 zmm13 zmm14 zmm15 zmm16 zmm17 zmm18 zmm19 zmm20 zmm21 zmm22 zmm23 zmm24 zmm25 zmm26 zmm27 zmm28 zmm29 zmm30 zmm31 k0 k1 k2 k3 k4 k5 k6 k7 bnd0 bnd1 bnd2 bnd3 cr0 cr1 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr8 tr3 tr4 tr5 tr6 tr7 r0 r1 r2 r3 r4 r5 r6 r7 r0b r1b r2b r3b r4b r5b r6b r7b r0w r1w r2w r3w r4w r5w r6w r7w r0d r1d r2d r3d r4d r5d r6d r7d r0h r1h r2h r3h r0l r1l r2l r3l r4l r5l r6l r7l r8l r9l r10l r11l r12l r13l r14l r15l db dw dd dq dt ddq do dy dz resb resw resd resq rest resdq reso resy resz incbin equ times byte word dword qword nosplit rel abs seg wrt strict near far a32 ptr",meta:"%define %xdefine %+ %undef %defstr %deftok %assign %strcat %strlen %substr %rotate %elif %else %endif %if %ifmacro %ifctx %ifidn %ifidni %ifid %ifnum %ifstr %iftoken %ifempty %ifenv %error %warning %fatal %rep %endrep %include %push %pop %repl %pathsearch %depend %use %arg %stacksize %local %line %comment %endcomment .nolist __FILE__ __LINE__ __SECT__ __BITS__ __OUTPUT_FORMAT__ __DATE__ __TIME__ __DATE_NUM__ __TIME_NUM__ __UTC_DATE__ __UTC_TIME__ __UTC_DATE_NUM__ __UTC_TIME_NUM__ __PASS__ struc endstruc istruc at iend align alignb sectalign daz nodaz up down zero default option assume public bits use16 use32 use64 default section segment absolute extern global common cpu float __utf16__ __utf16le__ __utf16be__ __utf32__ __utf32le__ __utf32be__ __float8__ __float16__ __float32__ __float64__ __float80m__ __float80e__ __float128l__ __float128h__ __Infinity__ __QNaN__ __SNaN__ Inf NaN QNaN SNaN float8 float16 float32 float64 float80m float80e float128l float128h __FLOAT_DAZ__ __FLOAT_ROUND__ __FLOAT__"},c:[s.C(";","$",{r:0}),{cN:"number",v:[{b:"\\b(?:([0-9][0-9_]*)?\\.[0-9_]*(?:[eE][+-]?[0-9_]+)?|(0[Xx])?[0-9][0-9_]*\\.?[0-9_]*(?:[pP](?:[+-]?[0-9_]+)?)?)\\b",r:0},{b:"\\$[0-9][0-9A-Fa-f]*",r:0},{b:"\\b(?:[0-9A-Fa-f][0-9A-Fa-f_]*[Hh]|[0-9][0-9_]*[DdTt]?|[0-7][0-7_]*[QqOo]|[0-1][0-1_]*[BbYy])\\b"},{b:"\\b(?:0[Xx][0-9A-Fa-f_]+|0[DdTt][0-9_]+|0[QqOo][0-7_]+|0[BbYy][0-1_]+)\\b"}]},s.QSM,{cN:"string",v:[{b:"'",e:"[^\\\\]'"},{b:"`",e:"[^\\\\]`"}],r:0},{cN:"symbol",v:[{b:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)"},{b:"^\\s*%%[A-Za-z0-9_$#@~.?]*:"}],r:0},{cN:"subst",b:"%[0-9]+",r:0},{cN:"subst",b:"%!S+",r:0},{cN:"meta",b:/^\s*\.[\w_-]+/}]}});hljs.registerLanguage("handlebars",function(e){var a={"builtin-name":"each in with if else unless bindattr action collection debugger log outlet template unbound view yield"};return{aliases:["hbs","html.hbs","html.handlebars"],cI:!0,sL:"xml",c:[e.C("{{!(--)?","(--)?}}"),{cN:"template-tag",b:/\{\{[#\/]/,e:/\}\}/,c:[{cN:"name",b:/[a-zA-Z\.-]+/,k:a,starts:{eW:!0,r:0,c:[e.QSM]}}]},{cN:"template-variable",b:/\{\{/,e:/\}\}/,k:a}]}});hljs.registerLanguage("scss",function(e){var t="[a-zA-Z-][a-zA-Z0-9_-]*",i={cN:"variable",b:"(\\$"+t+")\\b"},r={cN:"number",b:"#[0-9A-Fa-f]+"};({cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:!0,i:"[^\\s]",starts:{eW:!0,eE:!0,c:[r,e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"meta",b:"!important"}]}});return{cI:!0,i:"[=/|']",c:[e.CLCM,e.CBCM,{cN:"selector-id",b:"\\#[A-Za-z0-9_-]+",r:0},{cN:"selector-class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"selector-attr",b:"\\[",e:"\\]",i:"$"},{cN:"selector-tag",b:"\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\b",r:0},{b:":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)"},{b:"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)"},i,{cN:"attribute",b:"\\b(z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background-blend-mode|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b",i:"[^\\s]"},{b:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{b:":",e:";",c:[i,r,e.CSSNM,e.QSM,e.ASM,{cN:"meta",b:"!important"}]},{b:"@",e:"[{;]",k:"mixin include extend for if else each while charset import debug media page content font-face namespace warn",c:[i,e.QSM,e.ASM,r,e.CSSNM,{b:"\\s[A-Za-z0-9_.-]+",r:0}]}]}});hljs.registerLanguage("delphi",function(e){var r="exports register file shl array record property for mod while set ally label uses raise not stored class safecall var interface or private static exit index inherited to else stdcall override shr asm far resourcestring finalization packed virtual out and protected library do xorwrite goto near function end div overload object unit begin string on inline repeat until destructor write message program with read initialization except default nil if case cdecl in downto threadvar of try pascal const external constructor type public then implementation finally published procedure absolute reintroduce operator as is abstract alias assembler bitpacked break continue cppdecl cvar enumerator experimental platform deprecated unimplemented dynamic export far16 forward generic helper implements interrupt iochecks local name nodefault noreturn nostackframe oldfpccall otherwise saveregisters softfloat specialize strict unaligned varargs ",t=[e.CLCM,e.C(/\{/,/\}/,{r:0}),e.C(/\(\*/,/\*\)/,{r:10})],a={cN:"meta",v:[{b:/\{\$/,e:/\}/},{b:/\(\*\$/,e:/\*\)/}]},c={cN:"string",b:/'/,e:/'/,c:[{b:/''/}]},i={cN:"string",b:/(#\d+)+/},o={b:e.IR+"\\s*=\\s*class\\s*\\(",rB:!0,c:[e.TM]},n={cN:"function",bK:"function constructor destructor procedure",e:/[:;]/,k:"function constructor|10 destructor|10 procedure|10",c:[e.TM,{cN:"params",b:/\(/,e:/\)/,k:r,c:[c,i,a].concat(t)},a].concat(t)};return{aliases:["dpr","dfm","pas","pascal","freepascal","lazarus","lpr","lfm"],cI:!0,k:r,i:/"|\$[G-Zg-z]|\/\*|<\/|\|/,c:[c,i,e.NM,o,n,a].concat(t)}});hljs.registerLanguage("vhdl",function(e){var r="\\d(_|\\d)*",t="[eE][-+]?"+r,n=r+"(\\."+r+")?("+t+")?",o="\\w+",i=r+"#"+o+"(\\."+o+")?#("+t+")?",a="\\b("+i+"|"+n+")";return{cI:!0,k:{keyword:"abs access after alias all and architecture array assert assume assume_guarantee attribute begin block body buffer bus case component configuration constant context cover disconnect downto default else elsif end entity exit fairness file for force function generate generic group guarded if impure in inertial inout is label library linkage literal loop map mod nand new next nor not null of on open or others out package port postponed procedure process property protected pure range record register reject release rem report restrict restrict_guarantee return rol ror select sequence severity shared signal sla sll sra srl strong subtype then to transport type unaffected units until use variable vmode vprop vunit wait when while with xnor xor",built_in:"boolean bit character integer time delay_length natural positive string bit_vector file_open_kind file_open_status std_logic std_logic_vector unsigned signed boolean_vector integer_vector std_ulogic std_ulogic_vector unresolved_unsigned u_unsigned unresolved_signed u_signedreal_vector time_vector",literal:"false true note warning error failure line text side width"},i:"{",c:[e.CBCM,e.C("--","$"),e.QSM,{cN:"number",b:a,r:0},{cN:"string",b:"'(U|X|0|1|Z|W|L|H|-)'",c:[e.BE]},{cN:"symbol",b:"'[A-Za-z](_?[A-Za-z0-9])*",c:[e.BE]}]}});hljs.registerLanguage("accesslog",function(T){return{c:[{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+\\b",r:0},{cN:"string",b:'"(GET|POST|HEAD|PUT|DELETE|CONNECT|OPTIONS|PATCH|TRACE)',e:'"',k:"GET POST HEAD PUT DELETE CONNECT OPTIONS PATCH TRACE",i:"\\n",r:10},{cN:"string",b:/\[/,e:/\]/,i:"\\n"},{cN:"string",b:'"',e:'"',i:"\\n"}]}});hljs.registerLanguage("ini",function(e){var b={cN:"string",c:[e.BE],v:[{b:"'''",e:"'''",r:10},{b:'"""',e:'"""',r:10},{b:'"',e:'"'},{b:"'",e:"'"}]};return{aliases:["toml"],cI:!0,i:/\S/,c:[e.C(";","$"),e.HCM,{cN:"section",b:/^\s*\[+/,e:/\]+/},{b:/^[a-z0-9\[\]_-]+\s*=\s*/,e:"$",rB:!0,c:[{cN:"attr",b:/[a-z0-9\[\]_-]+/},{b:/=/,eW:!0,r:0,c:[{cN:"literal",b:/\bon|off|true|false|yes|no\b/},{cN:"variable",v:[{b:/\$[\w\d"][\w\d_]*/},{b:/\$\{(.*?)}/}]},b,{cN:"number",b:/([\+\-]+)?[\d]+_[\d_]+/},e.NM]}]}]}});hljs.registerLanguage("vbnet",function(e){return{aliases:["vb"],cI:!0,k:{keyword:"addhandler addressof alias and andalso aggregate ansi as assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into is isfalse isnot istrue join key let lib like loop me mid mod module mustinherit mustoverride mybase myclass namespace narrowing new next not notinheritable notoverridable of off on operator option optional or order orelse overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim rem removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly xor",built_in:"boolean byte cbool cbyte cchar cdate cdec cdbl char cint clng cobj csbyte cshort csng cstr ctype date decimal directcast double gettype getxmlnamespace iif integer long object sbyte short single string trycast typeof uinteger ulong ushort",literal:"true false nothing"},i:"//|{|}|endif|gosub|variant|wend",c:[e.inherit(e.QSM,{c:[{b:'""'}]}),e.C("'","$",{rB:!0,c:[{cN:"doctag",b:"'''|",c:[e.PWM]},{cN:"doctag",b:"",c:[e.PWM]}]}),e.CNM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elseif end region externalsource"}}]}});hljs.registerLanguage("gherkin",function(e){return{aliases:["feature"],k:"Feature Background Ability Business Need Scenario Scenarios Scenario Outline Scenario Template Examples Given And Then But When",c:[{cN:"symbol",b:"\\*",r:0},{cN:"meta",b:"@[^@\\s]+"},{b:"\\|",e:"\\|\\w*$",c:[{cN:"string",b:"[^|]+"}]},{cN:"variable",b:"<",e:">"},e.HCM,{cN:"string",b:'"""',e:'"""'},e.QSM]}});hljs.registerLanguage("maxima",function(e){var t="if then else elseif for thru do while unless step in and or not",a="true false unknown inf minf ind und %e %i %pi %phi %gamma",r=" abasep abs absint absolute_real_time acos acosh acot acoth acsc acsch activate addcol add_edge add_edges addmatrices addrow add_vertex add_vertices adjacency_matrix adjoin adjoint af agd airy airy_ai airy_bi airy_dai airy_dbi algsys alg_type alias allroots alphacharp alphanumericp amortization %and annuity_fv annuity_pv antid antidiff AntiDifference append appendfile apply apply1 apply2 applyb1 apropos args arit_amortization arithmetic arithsum array arrayapply arrayinfo arraymake arraysetapply ascii asec asech asin asinh askinteger asksign assoc assoc_legendre_p assoc_legendre_q assume assume_external_byte_order asympa at atan atan2 atanh atensimp atom atvalue augcoefmatrix augmented_lagrangian_method av average_degree backtrace bars barsplot barsplot_description base64 base64_decode bashindices batch batchload bc2 bdvac belln benefit_cost bern bernpoly bernstein_approx bernstein_expand bernstein_poly bessel bessel_i bessel_j bessel_k bessel_simplify bessel_y beta beta_incomplete beta_incomplete_generalized beta_incomplete_regularized bezout bfallroots bffac bf_find_root bf_fmin_cobyla bfhzeta bfloat bfloatp bfpsi bfpsi0 bfzeta biconnected_components bimetric binomial bipartition block blockmatrixp bode_gain bode_phase bothcoef box boxplot boxplot_description break bug_report build_info|10 buildq build_sample burn cabs canform canten cardinality carg cartan cartesian_product catch cauchy_matrix cbffac cdf_bernoulli cdf_beta cdf_binomial cdf_cauchy cdf_chi2 cdf_continuous_uniform cdf_discrete_uniform cdf_exp cdf_f cdf_gamma cdf_general_finite_discrete cdf_geometric cdf_gumbel cdf_hypergeometric cdf_laplace cdf_logistic cdf_lognormal cdf_negative_binomial cdf_noncentral_chi2 cdf_noncentral_student_t cdf_normal cdf_pareto cdf_poisson cdf_rank_sum cdf_rayleigh cdf_signed_rank cdf_student_t cdf_weibull cdisplay ceiling central_moment cequal cequalignore cf cfdisrep cfexpand cgeodesic cgreaterp cgreaterpignore changename changevar chaosgame charat charfun charfun2 charlist charp charpoly chdir chebyshev_t chebyshev_u checkdiv check_overlaps chinese cholesky christof chromatic_index chromatic_number cint circulant_graph clear_edge_weight clear_rules clear_vertex_label clebsch_gordan clebsch_graph clessp clesspignore close closefile cmetric coeff coefmatrix cograd col collapse collectterms columnop columnspace columnswap columnvector combination combine comp2pui compare compfile compile compile_file complement_graph complete_bipartite_graph complete_graph complex_number_p components compose_functions concan concat conjugate conmetderiv connected_components connect_vertices cons constant constantp constituent constvalue cont2part content continuous_freq contortion contour_plot contract contract_edge contragrad contrib_ode convert coord copy copy_file copy_graph copylist copymatrix cor cos cosh cot coth cov cov1 covdiff covect covers crc24sum create_graph create_list csc csch csetup cspline ctaylor ct_coordsys ctransform ctranspose cube_graph cuboctahedron_graph cunlisp cv cycle_digraph cycle_graph cylindrical days360 dblint deactivate declare declare_constvalue declare_dimensions declare_fundamental_dimensions declare_fundamental_units declare_qty declare_translated declare_unit_conversion declare_units declare_weights decsym defcon define define_alt_display define_variable defint defmatch defrule defstruct deftaylor degree_sequence del delete deleten delta demo demoivre denom depends derivdegree derivlist describe desolve determinant dfloat dgauss_a dgauss_b dgeev dgemm dgeqrf dgesv dgesvd diag diagmatrix diag_matrix diagmatrixp diameter diff digitcharp dimacs_export dimacs_import dimension dimensionless dimensions dimensions_as_list direct directory discrete_freq disjoin disjointp disolate disp dispcon dispform dispfun dispJordan display disprule dispterms distrib divide divisors divsum dkummer_m dkummer_u dlange dodecahedron_graph dotproduct dotsimp dpart draw draw2d draw3d drawdf draw_file draw_graph dscalar echelon edge_coloring edge_connectivity edges eigens_by_jacobi eigenvalues eigenvectors eighth einstein eivals eivects elapsed_real_time elapsed_run_time ele2comp ele2polynome ele2pui elem elementp elevation_grid elim elim_allbut eliminate eliminate_using ellipse elliptic_e elliptic_ec elliptic_eu elliptic_f elliptic_kc elliptic_pi ematrix empty_graph emptyp endcons entermatrix entertensor entier equal equalp equiv_classes erf erfc erf_generalized erfi errcatch error errormsg errors euler ev eval_string evenp every evolution evolution2d evundiff example exp expand expandwrt expandwrt_factored expint expintegral_chi expintegral_ci expintegral_e expintegral_e1 expintegral_ei expintegral_e_simplify expintegral_li expintegral_shi expintegral_si explicit explose exponentialize express expt exsec extdiff extract_linear_equations extremal_subset ezgcd %f f90 facsum factcomb factor factorfacsum factorial factorout factorsum facts fast_central_elements fast_linsolve fasttimes featurep fernfale fft fib fibtophi fifth filename_merge file_search file_type fillarray findde find_root find_root_abs find_root_error find_root_rel first fix flatten flength float floatnump floor flower_snark flush flush1deriv flushd flushnd flush_output fmin_cobyla forget fortran fourcos fourexpand fourier fourier_elim fourint fourintcos fourintsin foursimp foursin fourth fposition frame_bracket freeof freshline fresnel_c fresnel_s from_adjacency_matrix frucht_graph full_listify fullmap fullmapl fullratsimp fullratsubst fullsetify funcsolve fundamental_dimensions fundamental_units fundef funmake funp fv g0 g1 gamma gamma_greek gamma_incomplete gamma_incomplete_generalized gamma_incomplete_regularized gauss gauss_a gauss_b gaussprob gcd gcdex gcdivide gcfac gcfactor gd generalized_lambert_w genfact gen_laguerre genmatrix gensym geo_amortization geo_annuity_fv geo_annuity_pv geomap geometric geometric_mean geosum get getcurrentdirectory get_edge_weight getenv get_lu_factors get_output_stream_string get_pixel get_plot_option get_tex_environment get_tex_environment_default get_vertex_label gfactor gfactorsum ggf girth global_variances gn gnuplot_close gnuplot_replot gnuplot_reset gnuplot_restart gnuplot_start go Gosper GosperSum gr2d gr3d gradef gramschmidt graph6_decode graph6_encode graph6_export graph6_import graph_center graph_charpoly graph_eigenvalues graph_flow graph_order graph_periphery graph_product graph_size graph_union great_rhombicosidodecahedron_graph great_rhombicuboctahedron_graph grid_graph grind grobner_basis grotzch_graph hamilton_cycle hamilton_path hankel hankel_1 hankel_2 harmonic harmonic_mean hav heawood_graph hermite hessian hgfred hilbertmap hilbert_matrix hipow histogram histogram_description hodge horner hypergeometric i0 i1 %ibes ic1 ic2 ic_convert ichr1 ichr2 icosahedron_graph icosidodecahedron_graph icurvature ident identfor identity idiff idim idummy ieqn %if ifactors iframes ifs igcdex igeodesic_coords ilt image imagpart imetric implicit implicit_derivative implicit_plot indexed_tensor indices induced_subgraph inferencep inference_result infix info_display init_atensor init_ctensor in_neighbors innerproduct inpart inprod inrt integerp integer_partitions integrate intersect intersection intervalp intopois intosum invariant1 invariant2 inverse_fft inverse_jacobi_cd inverse_jacobi_cn inverse_jacobi_cs inverse_jacobi_dc inverse_jacobi_dn inverse_jacobi_ds inverse_jacobi_nc inverse_jacobi_nd inverse_jacobi_ns inverse_jacobi_sc inverse_jacobi_sd inverse_jacobi_sn invert invert_by_adjoint invert_by_lu inv_mod irr is is_biconnected is_bipartite is_connected is_digraph is_edge_in_graph is_graph is_graph_or_digraph ishow is_isomorphic isolate isomorphism is_planar isqrt isreal_p is_sconnected is_tree is_vertex_in_graph items_inference %j j0 j1 jacobi jacobian jacobi_cd jacobi_cn jacobi_cs jacobi_dc jacobi_dn jacobi_ds jacobi_nc jacobi_nd jacobi_ns jacobi_p jacobi_sc jacobi_sd jacobi_sn JF jn join jordan julia julia_set julia_sin %k kdels kdelta kill killcontext kostka kron_delta kronecker_product kummer_m kummer_u kurtosis kurtosis_bernoulli kurtosis_beta kurtosis_binomial kurtosis_chi2 kurtosis_continuous_uniform kurtosis_discrete_uniform kurtosis_exp kurtosis_f kurtosis_gamma kurtosis_general_finite_discrete kurtosis_geometric kurtosis_gumbel kurtosis_hypergeometric kurtosis_laplace kurtosis_logistic kurtosis_lognormal kurtosis_negative_binomial kurtosis_noncentral_chi2 kurtosis_noncentral_student_t kurtosis_normal kurtosis_pareto kurtosis_poisson kurtosis_rayleigh kurtosis_student_t kurtosis_weibull label labels lagrange laguerre lambda lambert_w laplace laplacian_matrix last lbfgs lc2kdt lcharp lc_l lcm lc_u ldefint ldisp ldisplay legendre_p legendre_q leinstein length let letrules letsimp levi_civita lfreeof lgtreillis lhs li liediff limit Lindstedt linear linearinterpol linear_program linear_regression line_graph linsolve listarray list_correlations listify list_matrix_entries list_nc_monomials listoftens listofvars listp lmax lmin load loadfile local locate_matrix_entry log logcontract log_gamma lopow lorentz_gauge lowercasep lpart lratsubst lreduce lriemann lsquares_estimates lsquares_estimates_approximate lsquares_estimates_exact lsquares_mse lsquares_residual_mse lsquares_residuals lsum ltreillis lu_backsub lucas lu_factor %m macroexpand macroexpand1 make_array makebox makefact makegamma make_graph make_level_picture makelist makeOrders make_poly_continent make_poly_country make_polygon make_random_state make_rgb_picture makeset make_string_input_stream make_string_output_stream make_transform mandelbrot mandelbrot_set map mapatom maplist matchdeclare matchfix mat_cond mat_fullunblocker mat_function mathml_display mat_norm matrix matrixmap matrixp matrix_size mattrace mat_trace mat_unblocker max max_clique max_degree max_flow maximize_lp max_independent_set max_matching maybe md5sum mean mean_bernoulli mean_beta mean_binomial mean_chi2 mean_continuous_uniform mean_deviation mean_discrete_uniform mean_exp mean_f mean_gamma mean_general_finite_discrete mean_geometric mean_gumbel mean_hypergeometric mean_laplace mean_logistic mean_lognormal mean_negative_binomial mean_noncentral_chi2 mean_noncentral_student_t mean_normal mean_pareto mean_poisson mean_rayleigh mean_student_t mean_weibull median median_deviation member mesh metricexpandall mgf1_sha1 min min_degree min_edge_cut minfactorial minimalPoly minimize_lp minimum_spanning_tree minor minpack_lsquares minpack_solve min_vertex_cover min_vertex_cut mkdir mnewton mod mode_declare mode_identity ModeMatrix moebius mon2schur mono monomial_dimensions multibernstein_poly multi_display_for_texinfo multi_elem multinomial multinomial_coeff multi_orbit multiplot_mode multi_pui multsym multthru mycielski_graph nary natural_unit nc_degree ncexpt ncharpoly negative_picture neighbors new newcontext newdet new_graph newline newton new_variable next_prime nicedummies niceindices ninth nofix nonarray noncentral_moment nonmetricity nonnegintegerp nonscalarp nonzeroandfreeof notequal nounify nptetrad npv nroots nterms ntermst nthroot nullity nullspace num numbered_boundaries numberp number_to_octets num_distinct_partitions numerval numfactor num_partitions nusum nzeta nzetai nzetar octets_to_number octets_to_oid odd_girth oddp ode2 ode_check odelin oid_to_octets op opena opena_binary openr openr_binary openw openw_binary operatorp opsubst optimize %or orbit orbits ordergreat ordergreatp orderless orderlessp orthogonal_complement orthopoly_recur orthopoly_weight outermap out_neighbors outofpois pade parabolic_cylinder_d parametric parametric_surface parg parGosper parse_string parse_timedate part part2cont partfrac partition partition_set partpol path_digraph path_graph pathname_directory pathname_name pathname_type pdf_bernoulli pdf_beta pdf_binomial pdf_cauchy pdf_chi2 pdf_continuous_uniform pdf_discrete_uniform pdf_exp pdf_f pdf_gamma pdf_general_finite_discrete pdf_geometric pdf_gumbel pdf_hypergeometric pdf_laplace pdf_logistic pdf_lognormal pdf_negative_binomial pdf_noncentral_chi2 pdf_noncentral_student_t pdf_normal pdf_pareto pdf_poisson pdf_rank_sum pdf_rayleigh pdf_signed_rank pdf_student_t pdf_weibull pearson_skewness permanent permut permutation permutations petersen_graph petrov pickapart picture_equalp picturep piechart piechart_description planar_embedding playback plog plot2d plot3d plotdf ploteq plsquares pochhammer points poisdiff poisexpt poisint poismap poisplus poissimp poissubst poistimes poistrim polar polarform polartorect polar_to_xy poly_add poly_buchberger poly_buchberger_criterion poly_colon_ideal poly_content polydecomp poly_depends_p poly_elimination_ideal poly_exact_divide poly_expand poly_expt poly_gcd polygon poly_grobner poly_grobner_equal poly_grobner_member poly_grobner_subsetp poly_ideal_intersection poly_ideal_polysaturation poly_ideal_polysaturation1 poly_ideal_saturation poly_ideal_saturation1 poly_lcm poly_minimization polymod poly_multiply polynome2ele polynomialp poly_normal_form poly_normalize poly_normalize_list poly_polysaturation_extension poly_primitive_part poly_pseudo_divide poly_reduced_grobner poly_reduction poly_saturation_extension poly_s_polynomial poly_subtract polytocompanion pop postfix potential power_mod powerseries powerset prefix prev_prime primep primes principal_components print printf printfile print_graph printpois printprops prodrac product properties propvars psi psubst ptriangularize pui pui2comp pui2ele pui2polynome pui_direct puireduc push put pv qput qrange qty quad_control quad_qag quad_qagi quad_qagp quad_qags quad_qawc quad_qawf quad_qawo quad_qaws quadrilateral quantile quantile_bernoulli quantile_beta quantile_binomial quantile_cauchy quantile_chi2 quantile_continuous_uniform quantile_discrete_uniform quantile_exp quantile_f quantile_gamma quantile_general_finite_discrete quantile_geometric quantile_gumbel quantile_hypergeometric quantile_laplace quantile_logistic quantile_lognormal quantile_negative_binomial quantile_noncentral_chi2 quantile_noncentral_student_t quantile_normal quantile_pareto quantile_poisson quantile_rayleigh quantile_student_t quantile_weibull quartile_skewness quit qunit quotient racah_v racah_w radcan radius random random_bernoulli random_beta random_binomial random_bipartite_graph random_cauchy random_chi2 random_continuous_uniform random_digraph random_discrete_uniform random_exp random_f random_gamma random_general_finite_discrete random_geometric random_graph random_graph1 random_gumbel random_hypergeometric random_laplace random_logistic random_lognormal random_negative_binomial random_network random_noncentral_chi2 random_noncentral_student_t random_normal random_pareto random_permutation random_poisson random_rayleigh random_regular_graph random_student_t random_tournament random_tree random_weibull range rank rat ratcoef ratdenom ratdiff ratdisrep ratexpand ratinterpol rational rationalize ratnumer ratnump ratp ratsimp ratsubst ratvars ratweight read read_array read_binary_array read_binary_list read_binary_matrix readbyte readchar read_hashed_array readline read_list read_matrix read_nested_list readonly read_xpm real_imagpart_to_conjugate realpart realroots rearray rectangle rectform rectform_log_if_constant recttopolar rediff reduce_consts reduce_order region region_boundaries region_boundaries_plus rem remainder remarray rembox remcomps remcon remcoord remfun remfunction remlet remove remove_constvalue remove_dimensions remove_edge remove_fundamental_dimensions remove_fundamental_units remove_plot_option remove_vertex rempart remrule remsym remvalue rename rename_file reset reset_displays residue resolvante resolvante_alternee1 resolvante_bipartite resolvante_diedrale resolvante_klein resolvante_klein3 resolvante_produit_sym resolvante_unitaire resolvante_vierer rest resultant return reveal reverse revert revert2 rgb2level rhs ricci riemann rinvariant risch rk rmdir rncombine romberg room rootscontract round row rowop rowswap rreduce run_testsuite %s save saving scalarp scaled_bessel_i scaled_bessel_i0 scaled_bessel_i1 scalefactors scanmap scatterplot scatterplot_description scene schur2comp sconcat scopy scsimp scurvature sdowncase sec sech second sequal sequalignore set_alt_display setdifference set_draw_defaults set_edge_weight setelmx setequalp setify setp set_partitions set_plot_option set_prompt set_random_state set_tex_environment set_tex_environment_default setunits setup_autoload set_up_dot_simplifications set_vertex_label seventh sexplode sf sha1sum sha256sum shortest_path shortest_weighted_path show showcomps showratvars sierpinskiale sierpinskimap sign signum similaritytransform simp_inequality simplify_sum simplode simpmetderiv simtran sin sinh sinsert sinvertcase sixth skewness skewness_bernoulli skewness_beta skewness_binomial skewness_chi2 skewness_continuous_uniform skewness_discrete_uniform skewness_exp skewness_f skewness_gamma skewness_general_finite_discrete skewness_geometric skewness_gumbel skewness_hypergeometric skewness_laplace skewness_logistic skewness_lognormal skewness_negative_binomial skewness_noncentral_chi2 skewness_noncentral_student_t skewness_normal skewness_pareto skewness_poisson skewness_rayleigh skewness_student_t skewness_weibull slength smake small_rhombicosidodecahedron_graph small_rhombicuboctahedron_graph smax smin smismatch snowmap snub_cube_graph snub_dodecahedron_graph solve solve_rec solve_rec_rat some somrac sort sparse6_decode sparse6_encode sparse6_export sparse6_import specint spherical spherical_bessel_j spherical_bessel_y spherical_hankel1 spherical_hankel2 spherical_harmonic spherical_to_xyz splice split sposition sprint sqfr sqrt sqrtdenest sremove sremovefirst sreverse ssearch ssort sstatus ssubst ssubstfirst staircase standardize standardize_inverse_trig starplot starplot_description status std std1 std_bernoulli std_beta std_binomial std_chi2 std_continuous_uniform std_discrete_uniform std_exp std_f std_gamma std_general_finite_discrete std_geometric std_gumbel std_hypergeometric std_laplace std_logistic std_lognormal std_negative_binomial std_noncentral_chi2 std_noncentral_student_t std_normal std_pareto std_poisson std_rayleigh std_student_t std_weibull stemplot stirling stirling1 stirling2 strim striml strimr string stringout stringp strong_components struve_h struve_l sublis sublist sublist_indices submatrix subsample subset subsetp subst substinpart subst_parallel substpart substring subvar subvarp sum sumcontract summand_to_rec supcase supcontext symbolp symmdifference symmetricp system take_channel take_inference tan tanh taylor taylorinfo taylorp taylor_simplifier taytorat tcl_output tcontract tellrat tellsimp tellsimpafter tentex tenth test_mean test_means_difference test_normality test_proportion test_proportions_difference test_rank_sum test_sign test_signed_rank test_variance test_variance_ratio tex tex1 tex_display texput %th third throw time timedate timer timer_info tldefint tlimit todd_coxeter toeplitz tokens to_lisp topological_sort to_poly to_poly_solve totaldisrep totalfourier totient tpartpol trace tracematrix trace_options transform_sample translate translate_file transpose treefale tree_reduce treillis treinat triangle triangularize trigexpand trigrat trigreduce trigsimp trunc truncate truncated_cube_graph truncated_dodecahedron_graph truncated_icosahedron_graph truncated_tetrahedron_graph tr_warnings_get tube tutte_graph ueivects uforget ultraspherical underlying_graph undiff union unique uniteigenvectors unitp units unit_step unitvector unorder unsum untellrat untimer untrace uppercasep uricci uriemann uvect vandermonde_matrix var var1 var_bernoulli var_beta var_binomial var_chi2 var_continuous_uniform var_discrete_uniform var_exp var_f var_gamma var_general_finite_discrete var_geometric var_gumbel var_hypergeometric var_laplace var_logistic var_lognormal var_negative_binomial var_noncentral_chi2 var_noncentral_student_t var_normal var_pareto var_poisson var_rayleigh var_student_t var_weibull vector vectorpotential vectorsimp verbify vers vertex_coloring vertex_connectivity vertex_degree vertex_distance vertex_eccentricity vertex_in_degree vertex_out_degree vertices vertices_to_cycle vertices_to_path %w weyl wheel_graph wiener_index wigner_3j wigner_6j wigner_9j with_stdout write_binary_data writebyte write_data writefile wronskian xreduce xthru %y Zeilberger zeroequiv zerofor zeromatrix zeromatrixp zeta zgeev zheev zlange zn_add_table zn_carmichael_lambda zn_characteristic_factors zn_determinant zn_factor_generators zn_invert_by_lu zn_log zn_mult_table absboxchar activecontexts adapt_depth additive adim aform algebraic algepsilon algexact aliases allbut all_dotsimp_denoms allocation allsym alphabetic animation antisymmetric arrays askexp assume_pos assume_pos_pred assumescalar asymbol atomgrad atrig1 axes axis_3d axis_bottom axis_left axis_right axis_top azimuth background background_color backsubst berlefact bernstein_explicit besselexpand beta_args_sum_to_integer beta_expand bftorat bftrunc bindtest border boundaries_array box boxchar breakup %c capping cauchysum cbrange cbtics center cflength cframe_flag cnonmet_flag color color_bar color_bar_tics colorbox columns commutative complex cone context contexts contour contour_levels cosnpiflag ctaypov ctaypt ctayswitch ctayvar ct_coords ctorsion_flag ctrgsimp cube current_let_rule_package cylinder data_file_name debugmode decreasing default_let_rule_package delay dependencies derivabbrev derivsubst detout diagmetric diff dim dimensions dispflag display2d|10 display_format_internal distribute_over doallmxops domain domxexpt domxmxops domxnctimes dontfactor doscmxops doscmxplus dot0nscsimp dot0simp dot1simp dotassoc dotconstrules dotdistrib dotexptsimp dotident dotscrules draw_graph_program draw_realpart edge_color edge_coloring edge_partition edge_type edge_width %edispflag elevation %emode endphi endtheta engineering_format_floats enhanced3d %enumer epsilon_lp erfflag erf_representation errormsg error_size error_syms error_type %e_to_numlog eval even evenfun evflag evfun ev_point expandwrt_denom expintexpand expintrep expon expop exptdispflag exptisolate exptsubst facexpand facsum_combine factlim factorflag factorial_expand factors_only fb feature features file_name file_output_append file_search_demo file_search_lisp file_search_maxima|10 file_search_tests file_search_usage file_type_lisp file_type_maxima|10 fill_color fill_density filled_func fixed_vertices flipflag float2bf font font_size fortindent fortspaces fpprec fpprintprec functions gamma_expand gammalim gdet genindex gensumnum GGFCFMAX GGFINFINITY globalsolve gnuplot_command gnuplot_curve_styles gnuplot_curve_titles gnuplot_default_term_command gnuplot_dumb_term_command gnuplot_file_args gnuplot_file_name gnuplot_out_file gnuplot_pdf_term_command gnuplot_pm3d gnuplot_png_term_command gnuplot_postamble gnuplot_preamble gnuplot_ps_term_command gnuplot_svg_term_command gnuplot_term gnuplot_view_args Gosper_in_Zeilberger gradefs grid grid2d grind halfangles head_angle head_both head_length head_type height hypergeometric_representation %iargs ibase icc1 icc2 icounter idummyx ieqnprint ifb ifc1 ifc2 ifg ifgi ifr iframe_bracket_form ifri igeowedge_flag ikt1 ikt2 imaginary inchar increasing infeval infinity inflag infolists inm inmc1 inmc2 intanalysis integer integervalued integrate_use_rootsof integration_constant integration_constant_counter interpolate_color intfaclim ip_grid ip_grid_in irrational isolate_wrt_times iterations itr julia_parameter %k1 %k2 keepfloat key key_pos kinvariant kt label label_alignment label_orientation labels lassociative lbfgs_ncorrections lbfgs_nfeval_max leftjust legend letrat let_rule_packages lfg lg lhospitallim limsubst linear linear_solver linechar linel|10 linenum line_type linewidth line_width linsolve_params linsolvewarn lispdisp listarith listconstvars listdummyvars lmxchar load_pathname loadprint logabs logarc logcb logconcoeffp logexpand lognegint logsimp logx logx_secondary logy logy_secondary logz lriem m1pbranch macroexpansion macros mainvar manual_demo maperror mapprint matrix_element_add matrix_element_mult matrix_element_transpose maxapplydepth maxapplyheight maxima_tempdir|10 maxima_userdir|10 maxnegex MAX_ORD maxposex maxpsifracdenom maxpsifracnum maxpsinegint maxpsiposint maxtayorder mesh_lines_color method mod_big_prime mode_check_errorp mode_checkp mode_check_warnp mod_test mod_threshold modular_linear_solver modulus multiplicative multiplicities myoptions nary negdistrib negsumdispflag newline newtonepsilon newtonmaxiter nextlayerfactor niceindicespref nm nmc noeval nolabels nonegative_lp noninteger nonscalar noun noundisp nouns np npi nticks ntrig numer numer_pbranch obase odd oddfun opacity opproperties opsubst optimprefix optionset orientation origin orthopoly_returns_intervals outative outchar packagefile palette partswitch pdf_file pfeformat phiresolution %piargs piece pivot_count_sx pivot_max_sx plot_format plot_options plot_realpart png_file pochhammer_max_index points pointsize point_size points_joined point_type poislim poisson poly_coefficient_ring poly_elimination_order polyfactor poly_grobner_algorithm poly_grobner_debug poly_monomial_order poly_primary_elimination_order poly_return_term_list poly_secondary_elimination_order poly_top_reduction_only posfun position powerdisp pred prederror primep_number_of_tests product_use_gamma program programmode promote_float_to_bigfloat prompt proportional_axes props psexpand ps_file radexpand radius radsubstflag rassociative ratalgdenom ratchristof ratdenomdivide rateinstein ratepsilon ratfac rational ratmx ratprint ratriemann ratsimpexpons ratvarswitch ratweights ratweyl ratwtlvl real realonly redraw refcheck resolution restart resultant ric riem rmxchar %rnum_list rombergabs rombergit rombergmin rombergtol rootsconmode rootsepsilon run_viewer same_xy same_xyz savedef savefactors scalar scalarmatrixp scale scale_lp setcheck setcheckbreak setval show_edge_color show_edges show_edge_type show_edge_width show_id show_label showtime show_vertex_color show_vertex_size show_vertex_type show_vertices show_weight simp simplified_output simplify_products simpproduct simpsum sinnpiflag solvedecomposes solveexplicit solvefactors solvenullwarn solveradcan solvetrigwarn space sparse sphere spring_embedding_depth sqrtdispflag stardisp startphi starttheta stats_numer stringdisp structures style sublis_apply_lambda subnumsimp sumexpand sumsplitfact surface surface_hide svg_file symmetric tab taylordepth taylor_logexpand taylor_order_coefficients taylor_truncate_polynomials tensorkill terminal testsuite_files thetaresolution timer_devalue title tlimswitch tr track transcompile transform transform_xy translate_fast_arrays transparent transrun tr_array_as_ref tr_bound_function_applyp tr_file_tty_messagesp tr_float_can_branch_complex tr_function_call_default trigexpandplus trigexpandtimes triginverses trigsign trivial_solutions tr_numer tr_optimize_max_loop tr_semicompile tr_state_vars tr_warn_bad_function_calls tr_warn_fexpr tr_warn_meval tr_warn_mode tr_warn_undeclared tr_warn_undefined_variable tstep ttyoff tube_extremes ufg ug %unitexpand unit_vectors uric uriem use_fast_arrays user_preamble usersetunits values vect_cross verbose vertex_color vertex_coloring vertex_partition vertex_size vertex_type view warnings weyl width windowname windowtitle wired_surface wireframe xaxis xaxis_color xaxis_secondary xaxis_type xaxis_width xlabel xlabel_secondary xlength xrange xrange_secondary xtics xtics_axis xtics_rotate xtics_rotate_secondary xtics_secondary xtics_secondary_axis xu_grid x_voxel xy_file xyplane xy_scale yaxis yaxis_color yaxis_secondary yaxis_type yaxis_width ylabel ylabel_secondary ylength yrange yrange_secondary ytics ytics_axis ytics_rotate ytics_rotate_secondary ytics_secondary ytics_secondary_axis yv_grid y_voxel yx_ratio zaxis zaxis_color zaxis_type zaxis_width zeroa zerob zerobern zeta%pi zlabel zlabel_rotate zlength zmin zn_primroot_limit zn_primroot_pretest",i="_ __ %|0 %%|0";return{l:"[A-Za-z_%][0-9A-Za-z_%]*",k:{keyword:t,literal:a,built_in:r,symbol:i},c:[{cN:"comment",b:"/\\*",e:"\\*/",c:["self"]},e.QSM,{cN:"number",r:0,v:[{b:"\\b(\\d+|\\d+\\.|\\.\\d+|\\d+\\.\\d+)[Ee][-+]?\\d+\\b"},{b:"\\b(\\d+|\\d+\\.|\\.\\d+|\\d+\\.\\d+)[Bb][-+]?\\d+\\b",r:10},{b:"\\b(\\.\\d+|\\d+\\.\\d+)\\b"},{b:"\\b(\\d+|0[0-9A-Za-z]+)\\.?\\b"}]}],i:/@/}});hljs.registerLanguage("parser3",function(r){var e=r.C("{","}",{c:["self"]});return{sL:"xml",r:0,c:[r.C("^#","$"),r.C("\\^rem{","}",{r:10,c:[e]}),{cN:"meta",b:"^@(?:BASE|USE|CLASS|OPTIONS)$",r:10},{cN:"title",b:"@[\\w\\-]+\\[[\\w^;\\-]*\\](?:\\[[\\w^;\\-]*\\])?(?:.*)$"},{cN:"variable",b:"\\$\\{?[\\w\\-\\.\\:]+\\}?"},{cN:"keyword",b:"\\^[\\w\\-\\.\\:]+"},{cN:"number",b:"\\^#[0-9a-fA-F]+"},r.CNM]}});hljs.registerLanguage("go",function(e){var t={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",literal:"true false iota nil",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{aliases:["golang"],k:t,i:"|->)',c:[t,a,e.CLCM,n,o,e.NM,i,{cN:"class",b:"=\\bclass\\b",e:"end;",k:r,c:[n,o,t,a,e.CLCM,i]}]}});hljs.registerLanguage("ada",function(e){var r="\\d(_|\\d)*",t="[eE][-+]?"+r,s=r+"(\\."+r+")?("+t+")?",n="\\w+",a=r+"#"+n+"(\\."+n+")?#("+t+")?",i="\\b("+a+"|"+s+")",c="[A-Za-z](_?[A-Za-z0-9.])*",o="[]{}%#'\"",b=e.C("--","$"),d={b:"\\s+:\\s+",e:"\\s*(:=|;|\\)|=>|$)",i:o,c:[{bK:"loop for declare others",endsParent:!0},{cN:"keyword",bK:"not null constant access function procedure in out aliased exception"},{cN:"type",b:c,endsParent:!0,r:0}]};return{cI:!0,k:{keyword:"abort else new return abs elsif not reverse abstract end accept entry select access exception of separate aliased exit or some all others subtype and for out synchronized array function overriding at tagged generic package task begin goto pragma terminate body private then if procedure type case in protected constant interface is raise use declare range delay limited record when delta loop rem while digits renames with do mod requeue xor",literal:"True False"},c:[b,{cN:"string",b:/"/,e:/"/,c:[{b:/""/,r:0}]},{cN:"string",b:/'.'/},{cN:"number",b:i,r:0},{cN:"symbol",b:"'"+c},{cN:"title",b:"(\\bwith\\s+)?(\\bprivate\\s+)?\\bpackage\\s+(\\bbody\\s+)?",e:"(is|$)",k:"package body",eB:!0,eE:!0,i:o},{b:"(\\b(with|overriding)\\s+)?\\b(function|procedure)\\s+",e:"(\\bis|\\bwith|\\brenames|\\)\\s*;)",k:"overriding function procedure with is renames return",rB:!0,c:[b,{cN:"title",b:"(\\bwith\\s+)?\\b(function|procedure)\\s+",e:"(\\(|\\s+|$)",eB:!0,eE:!0,i:o},d,{cN:"type",b:"\\breturn\\s+",e:"(\\s+|;|$)",k:"return",eB:!0,eE:!0,endsParent:!0,i:o}]},{cN:"type",b:"\\b(sub)?type\\s+",e:"\\s+",k:"type",eB:!0,i:o},d]}});hljs.registerLanguage("flix",function(e){var t={cN:"string",b:/'(.|\\[xXuU][a-zA-Z0-9]+)'/},i={cN:"string",v:[{b:'"',e:'"'}]},n={cN:"title",b:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/},c={cN:"function",bK:"def",e:/[:={\[(\n;]/,eE:!0,c:[n]};return{k:{literal:"true false",keyword:"case class def else enum if impl import in lat rel index let match namespace switch type yield with"},c:[e.CLCM,e.CBCM,t,i,c,e.CNM]}});hljs.registerLanguage("cmake",function(e){return{aliases:["cmake.in"],cI:!0,k:{keyword:"add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory break build_command cmake_minimum_required cmake_policy configure_file create_test_sourcelist define_property else elseif enable_language enable_testing endforeach endfunction endif endmacro endwhile execute_process export find_file find_library find_package find_path find_program fltk_wrap_ui foreach function get_cmake_property get_directory_property get_filename_component get_property get_source_file_property get_target_property get_test_property if include include_directories include_external_msproject include_regular_expression install link_directories load_cache load_command macro mark_as_advanced message option output_required_files project qt_wrap_cpp qt_wrap_ui remove_definitions return separate_arguments set set_directory_properties set_property set_source_files_properties set_target_properties set_tests_properties site_name source_group string target_link_libraries try_compile try_run unset variable_watch while build_name exec_program export_library_dependencies install_files install_programs install_targets link_libraries make_directory remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file qt5_use_modules qt5_use_package qt5_wrap_cpp on off true false and or equal less greater strless strgreater strequal matches"},c:[{cN:"variable",b:"\\${",e:"}"},e.HCM,e.QSM,e.NM]}});hljs.registerLanguage("python",function(e){var r={keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},b={cN:"meta",b:/^(>>>|\.\.\.) /},c={cN:"subst",b:/\{/,e:/\}/,k:r,i:/#/},a={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[b],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[b],r:10},{b:/(fr|rf|f)'''/,e:/'''/,c:[b,c]},{b:/(fr|rf|f)"""/,e:/"""/,c:[b,c]},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},{b:/(fr|rf|f)'/,e:/'/,c:[c]},{b:/(fr|rf|f)"/,e:/"/,c:[c]},e.ASM,e.QSM]},s={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},i={cN:"params",b:/\(/,e:/\)/,c:["self",b,s,a]};return c.c=[a,s,b],{aliases:["py","gyp"],k:r,i:/(<\/|->|\?)|=>/,c:[b,s,a,e.HCM,{v:[{cN:"function",bK:"def"},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,i,{b:/->/,eW:!0,k:"None"}]},{cN:"meta",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}});hljs.registerLanguage("coffeescript",function(e){var c={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super yield import export from as default await then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",built_in:"npm require console print module global window document"},n="[A-Za-z$_][0-9A-Za-z$_]*",r={cN:"subst",b:/#\{/,e:/}/,k:c},i=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,r]},{b:/"/,e:/"/,c:[e.BE,r]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[r,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{b:"@"+n},{sL:"javascript",eB:!0,eE:!0,v:[{b:"```",e:"```"},{b:"`",e:"`"}]}];r.c=i;var s=e.inherit(e.TM,{b:n}),t="(\\(.*\\))?\\s*\\B[-=]>",o={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:c,c:["self"].concat(i)}]};return{aliases:["coffee","cson","iced"],k:c,i:/\/\*/,c:i.concat([e.C("###","###"),e.HCM,{cN:"function",b:"^\\s*"+n+"\\s*=\\s*"+t,e:"[-=]>",rB:!0,c:[s,o]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:t,e:"[-=]>",rB:!0,c:[o]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[s]},s]},{b:n+":",e:":",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage("basic",function(E){return{cI:!0,i:"^.",l:"[a-zA-Z][a-zA-Z0-9_$%!#]*",k:{keyword:"ABS ASC AND ATN AUTO|0 BEEP BLOAD|10 BSAVE|10 CALL CALLS CDBL CHAIN CHDIR CHR$|10 CINT CIRCLE CLEAR CLOSE CLS COLOR COM COMMON CONT COS CSNG CSRLIN CVD CVI CVS DATA DATE$ DEFDBL DEFINT DEFSNG DEFSTR DEF|0 SEG USR DELETE DIM DRAW EDIT END ENVIRON ENVIRON$ EOF EQV ERASE ERDEV ERDEV$ ERL ERR ERROR EXP FIELD FILES FIX FOR|0 FRE GET GOSUB|10 GOTO HEX$ IF|0 THEN ELSE|0 INKEY$ INP INPUT INPUT# INPUT$ INSTR IMP INT IOCTL IOCTL$ KEY ON OFF LIST KILL LEFT$ LEN LET LINE LLIST LOAD LOC LOCATE LOF LOG LPRINT USING LSET MERGE MID$ MKDIR MKD$ MKI$ MKS$ MOD NAME NEW NEXT NOISE NOT OCT$ ON OR PEN PLAY STRIG OPEN OPTION BASE OUT PAINT PALETTE PCOPY PEEK PMAP POINT POKE POS PRINT PRINT] PSET PRESET PUT RANDOMIZE READ REM RENUM RESET|0 RESTORE RESUME RETURN|0 RIGHT$ RMDIR RND RSET RUN SAVE SCREEN SGN SHELL SIN SOUND SPACE$ SPC SQR STEP STICK STOP STR$ STRING$ SWAP SYSTEM TAB TAN TIME$ TIMER TROFF TRON TO USR VAL VARPTR VARPTR$ VIEW WAIT WHILE WEND WIDTH WINDOW WRITE XOR"},c:[E.QSM,E.C("REM","$",{r:10}),E.C("'","$",{r:0}),{cN:"symbol",b:"^[0-9]+ ",r:10},{cN:"number",b:"\\b([0-9]+[0-9edED.]*[#!]?)",r:0},{cN:"number",b:"(&[hH][0-9a-fA-F]{1,4})"},{cN:"number",b:"(&[oO][0-7]{1,6})"}]}});hljs.registerLanguage("ocaml",function(e){return{aliases:["ml"],k:{keyword:"and as assert asr begin class constraint do done downto else end exception external for fun function functor if in include inherit! inherit initializer land lazy let lor lsl lsr lxor match method!|10 method mod module mutable new object of open! open or private rec sig struct then to try type val! val virtual when while with parser value",built_in:"array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 string unit in_channel out_channel ref",literal:"true false"},i:/\/\/|>>/,l:"[a-z_]\\w*!?",c:[{cN:"literal",b:"\\[(\\|\\|)?\\]|\\(\\)",r:0},e.C("\\(\\*","\\*\\)",{c:["self"]}),{cN:"symbol",b:"'[A-Za-z_](?!')[\\w']*"},{cN:"type",b:"`[A-Z][\\w']*"},{cN:"type",b:"\\b[A-Z][\\w']*",r:0},{b:"[a-z_]\\w*'[\\w']*",r:0},e.inherit(e.ASM,{cN:"string",r:0}),e.inherit(e.QSM,{i:null}),{cN:"number",b:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",r:0},{b:/[-=]>/}]}});hljs.registerLanguage("tap",function(b){return{cI:!0,c:[b.HCM,{cN:"meta",v:[{b:"^TAP version (\\d+)$"},{b:"^1\\.\\.(\\d+)$"}]},{b:"(s+)?---$",e:"\\.\\.\\.$",sL:"yaml",r:0},{cN:"number",b:" (\\d+) "},{cN:"symbol",v:[{b:"^ok"},{b:"^not ok"}]}]}});hljs.registerLanguage("haskell",function(e){var i={v:[e.C("--","$"),e.C("{-","-}",{c:["self"]})]},a={cN:"meta",b:"{-#",e:"#-}"},l={cN:"meta",b:"^#",e:"$"},c={cN:"type",b:"\\b[A-Z][\\w']*",r:0},n={b:"\\(",e:"\\)",i:'"',c:[a,l,{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},e.inherit(e.TM,{b:"[_a-z][\\w']*"}),i]},s={b:"{",e:"}",c:n.c};return{aliases:["hs"],k:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec",c:[{bK:"module",e:"where",k:"module where",c:[n,i],i:"\\W\\.|;"},{b:"\\bimport\\b",e:"$",k:"import qualified as hiding",c:[n,i],i:"\\W\\.|;"},{cN:"class",b:"^(\\s*)?(class|instance)\\b",e:"where",k:"class family instance where",c:[c,n,i]},{cN:"class",b:"\\b(data|(new)?type)\\b",e:"$",k:"data family type newtype deriving",c:[a,c,n,s,i]},{bK:"default",e:"$",c:[c,n,i]},{bK:"infix infixl infixr",e:"$",c:[e.CNM,i]},{b:"\\bforeign\\b",e:"$",k:"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe",c:[c,e.QSM,i]},{cN:"meta",b:"#!\\/usr\\/bin\\/env runhaskell",e:"$"},a,l,e.QSM,e.CNM,c,e.inherit(e.TM,{b:"^[_a-z][\\w']*"}),i,{b:"->|<-"}]}});hljs.registerLanguage("mojolicious",function(e){return{sL:"xml",c:[{cN:"meta",b:"^__(END|DATA)__$"},{b:"^\\s*%{1,2}={0,2}",e:"$",sL:"perl"},{b:"<%{1,2}={0,2}",e:"={0,1}%>",sL:"perl",eB:!0,eE:!0}]}});hljs.registerLanguage("livecodeserver",function(e){var r={b:"\\b[gtps][A-Z]+[A-Za-z0-9_\\-]*\\b|\\$_[A-Z]+",r:0},t=[e.CBCM,e.HCM,e.C("--","$"),e.C("[^:]//","$")],a=e.inherit(e.TM,{v:[{b:"\\b_*rig[A-Z]+[A-Za-z0-9_\\-]*"},{b:"\\b_[a-z0-9\\-]+"}]}),o=e.inherit(e.TM,{b:"\\b([A-Za-z0-9_\\-]+)\\b"});return{cI:!1,k:{keyword:"$_COOKIE $_FILES $_GET $_GET_BINARY $_GET_RAW $_POST $_POST_BINARY $_POST_RAW $_SESSION $_SERVER codepoint codepoints segment segments codeunit codeunits sentence sentences trueWord trueWords paragraph after byte bytes english the until http forever descending using line real8 with seventh for stdout finally element word words fourth before black ninth sixth characters chars stderr uInt1 uInt1s uInt2 uInt2s stdin string lines relative rel any fifth items from middle mid at else of catch then third it file milliseconds seconds second secs sec int1 int1s int4 int4s internet int2 int2s normal text item last long detailed effective uInt4 uInt4s repeat end repeat URL in try into switch to words https token binfile each tenth as ticks tick system real4 by dateItems without char character ascending eighth whole dateTime numeric short first ftp integer abbreviated abbr abbrev private case while if div mod wrap and or bitAnd bitNot bitOr bitXor among not in a an within contains ends with begins the keys of keys",literal:"SIX TEN FORMFEED NINE ZERO NONE SPACE FOUR FALSE COLON CRLF PI COMMA ENDOFFILE EOF EIGHT FIVE QUOTE EMPTY ONE TRUE RETURN CR LINEFEED RIGHT BACKSLASH NULL SEVEN TAB THREE TWO six ten formfeed nine zero none space four false colon crlf pi comma endoffile eof eight five quote empty one true return cr linefeed right backslash null seven tab three two RIVERSION RISTATE FILE_READ_MODE FILE_WRITE_MODE FILE_WRITE_MODE DIR_WRITE_MODE FILE_READ_UMASK FILE_WRITE_UMASK DIR_READ_UMASK DIR_WRITE_UMASK",built_in:"put abs acos aliasReference annuity arrayDecode arrayEncode asin atan atan2 average avg avgDev base64Decode base64Encode baseConvert binaryDecode binaryEncode byteOffset byteToNum cachedURL cachedURLs charToNum cipherNames codepointOffset codepointProperty codepointToNum codeunitOffset commandNames compound compress constantNames cos date dateFormat decompress directories diskSpace DNSServers exp exp1 exp2 exp10 extents files flushEvents folders format functionNames geometricMean global globals hasMemory harmonicMean hostAddress hostAddressToName hostName hostNameToAddress isNumber ISOToMac itemOffset keys len length libURLErrorData libUrlFormData libURLftpCommand libURLLastHTTPHeaders libURLLastRHHeaders libUrlMultipartFormAddPart libUrlMultipartFormData libURLVersion lineOffset ln ln1 localNames log log2 log10 longFilePath lower macToISO matchChunk matchText matrixMultiply max md5Digest median merge millisec millisecs millisecond milliseconds min monthNames nativeCharToNum normalizeText num number numToByte numToChar numToCodepoint numToNativeChar offset open openfiles openProcesses openProcessIDs openSockets paragraphOffset paramCount param params peerAddress pendingMessages platform popStdDev populationStandardDeviation populationVariance popVariance processID random randomBytes replaceText result revCreateXMLTree revCreateXMLTreeFromFile revCurrentRecord revCurrentRecordIsFirst revCurrentRecordIsLast revDatabaseColumnCount revDatabaseColumnIsNull revDatabaseColumnLengths revDatabaseColumnNames revDatabaseColumnNamed revDatabaseColumnNumbered revDatabaseColumnTypes revDatabaseConnectResult revDatabaseCursors revDatabaseID revDatabaseTableNames revDatabaseType revDataFromQuery revdb_closeCursor revdb_columnbynumber revdb_columncount revdb_columnisnull revdb_columnlengths revdb_columnnames revdb_columntypes revdb_commit revdb_connect revdb_connections revdb_connectionerr revdb_currentrecord revdb_cursorconnection revdb_cursorerr revdb_cursors revdb_dbtype revdb_disconnect revdb_execute revdb_iseof revdb_isbof revdb_movefirst revdb_movelast revdb_movenext revdb_moveprev revdb_query revdb_querylist revdb_recordcount revdb_rollback revdb_tablenames revGetDatabaseDriverPath revNumberOfRecords revOpenDatabase revOpenDatabases revQueryDatabase revQueryDatabaseBlob revQueryResult revQueryIsAtStart revQueryIsAtEnd revUnixFromMacPath revXMLAttribute revXMLAttributes revXMLAttributeValues revXMLChildContents revXMLChildNames revXMLCreateTreeFromFileWithNamespaces revXMLCreateTreeWithNamespaces revXMLDataFromXPathQuery revXMLEvaluateXPath revXMLFirstChild revXMLMatchingNode revXMLNextSibling revXMLNodeContents revXMLNumberOfChildren revXMLParent revXMLPreviousSibling revXMLRootNode revXMLRPC_CreateRequest revXMLRPC_Documents revXMLRPC_Error revXMLRPC_GetHost revXMLRPC_GetMethod revXMLRPC_GetParam revXMLText revXMLRPC_Execute revXMLRPC_GetParamCount revXMLRPC_GetParamNode revXMLRPC_GetParamType revXMLRPC_GetPath revXMLRPC_GetPort revXMLRPC_GetProtocol revXMLRPC_GetRequest revXMLRPC_GetResponse revXMLRPC_GetSocket revXMLTree revXMLTrees revXMLValidateDTD revZipDescribeItem revZipEnumerateItems revZipOpenArchives round sampVariance sec secs seconds sentenceOffset sha1Digest shell shortFilePath sin specialFolderPath sqrt standardDeviation statRound stdDev sum sysError systemVersion tan tempName textDecode textEncode tick ticks time to tokenOffset toLower toUpper transpose truewordOffset trunc uniDecode uniEncode upper URLDecode URLEncode URLStatus uuid value variableNames variance version waitDepth weekdayNames wordOffset xsltApplyStylesheet xsltApplyStylesheetFromFile xsltLoadStylesheet xsltLoadStylesheetFromFile add breakpoint cancel clear local variable file word line folder directory URL close socket process combine constant convert create new alias folder directory decrypt delete variable word line folder directory URL dispatch divide do encrypt filter get include intersect kill libURLDownloadToFile libURLFollowHttpRedirects libURLftpUpload libURLftpUploadFile libURLresetAll libUrlSetAuthCallback libURLSetCustomHTTPHeaders libUrlSetExpect100 libURLSetFTPListCommand libURLSetFTPMode libURLSetFTPStopTime libURLSetStatusCallback load multiply socket prepare process post seek rel relative read from process rename replace require resetAll resolve revAddXMLNode revAppendXML revCloseCursor revCloseDatabase revCommitDatabase revCopyFile revCopyFolder revCopyXMLNode revDeleteFolder revDeleteXMLNode revDeleteAllXMLTrees revDeleteXMLTree revExecuteSQL revGoURL revInsertXMLNode revMoveFolder revMoveToFirstRecord revMoveToLastRecord revMoveToNextRecord revMoveToPreviousRecord revMoveToRecord revMoveXMLNode revPutIntoXMLNode revRollBackDatabase revSetDatabaseDriverPath revSetXMLAttribute revXMLRPC_AddParam revXMLRPC_DeleteAllDocuments revXMLAddDTD revXMLRPC_Free revXMLRPC_FreeAll revXMLRPC_DeleteDocument revXMLRPC_DeleteParam revXMLRPC_SetHost revXMLRPC_SetMethod revXMLRPC_SetPort revXMLRPC_SetProtocol revXMLRPC_SetSocket revZipAddItemWithData revZipAddItemWithFile revZipAddUncompressedItemWithData revZipAddUncompressedItemWithFile revZipCancel revZipCloseArchive revZipDeleteItem revZipExtractItemToFile revZipExtractItemToVariable revZipSetProgressCallback revZipRenameItem revZipReplaceItemWithData revZipReplaceItemWithFile revZipOpenArchive send set sort split start stop subtract union unload wait write"},c:[r,{cN:"keyword",b:"\\bend\\sif\\b"},{cN:"function",bK:"function",e:"$",c:[r,o,e.ASM,e.QSM,e.BNM,e.CNM,a]},{cN:"function",b:"\\bend\\s+",e:"$",k:"end",c:[o,a],r:0},{bK:"command on",e:"$",c:[r,o,e.ASM,e.QSM,e.BNM,e.CNM,a]},{cN:"meta",v:[{b:"<\\?(rev|lc|livecode)",r:10},{b:"<\\?"},{b:"\\?>"}]},e.ASM,e.QSM,e.BNM,e.CNM,a].concat(t),i:";$|^\\[|^=|&|{"}});hljs.registerLanguage("leaf",function(e){return{c:[{cN:"function",b:"#+[A-Za-z_0-9]*\\(",e:" {",rB:!0,eE:!0,c:[{cN:"keyword",b:"#+"},{cN:"title",b:"[A-Za-z_][A-Za-z_0-9]*"},{cN:"params",b:"\\(",e:"\\)",endsParent:!0,c:[{cN:"string",b:'"',e:'"'},{cN:"variable",b:"[A-Za-z_][A-Za-z_0-9]*"}]}]}]}});hljs.registerLanguage("shell",function(s){return{aliases:["console"],c:[{cN:"meta",b:"^\\s{0,3}[\\w\\d\\[\\]()@-]*[>%$#]",starts:{e:"$",sL:"bash"}}]}});hljs.registerLanguage("smalltalk",function(e){var s="[a-z][a-zA-Z0-9_]*",a={cN:"string",b:"\\$.{1}"},r={cN:"symbol",b:"#"+e.UIR};return{aliases:["st"],k:"self super nil true false thisContext",c:[e.C('"','"'),e.ASM,{cN:"type",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},{b:s+":",r:0},e.CNM,r,a,{b:"\\|[ ]*"+s+"([ ]+"+s+")*[ ]*\\|",rB:!0,e:/\|/,i:/\S/,c:[{b:"(\\|[ ]*)?"+s}]},{b:"\\#\\(",e:"\\)",c:[e.ASM,a,e.CNM,r]}]}});hljs.registerLanguage("brainfuck",function(r){var n={cN:"literal",b:"[\\+\\-]",r:0};return{aliases:["bf"],c:[r.C("[^\\[\\]\\.,\\+\\-<> \r\n]","[\\[\\]\\.,\\+\\-<> \r\n]",{rE:!0,r:0}),{cN:"title",b:"[\\[\\]]",r:0},{cN:"string",b:"[\\.,]",r:0},{b:/\+\+|\-\-/,rB:!0,c:[n]},n]}});hljs.registerLanguage("q",function(e){var s={keyword:"do while select delete by update from",literal:"0b 1b",built_in:"neg not null string reciprocal floor ceiling signum mod xbar xlog and or each scan over prior mmu lsq inv md5 ltime gtime count first var dev med cov cor all any rand sums prds mins maxs fills deltas ratios avgs differ prev next rank reverse iasc idesc asc desc msum mcount mavg mdev xrank mmin mmax xprev rotate distinct group where flip type key til get value attr cut set upsert raze union inter except cross sv vs sublist enlist read0 read1 hopen hclose hdel hsym hcount peach system ltrim rtrim trim lower upper ssr view tables views cols xcols keys xkey xcol xasc xdesc fkeys meta lj aj aj0 ij pj asof uj ww wj wj1 fby xgroup ungroup ej save load rsave rload show csv parse eval min max avg wavg wsum sin cos tan sum",type:"`float `double int `timestamp `timespan `datetime `time `boolean `symbol `char `byte `short `long `real `month `date `minute `second `guid"};return{aliases:["k","kdb"],k:s,l:/(`?)[A-Za-z0-9_]+\b/,c:[e.CLCM,e.QSM,e.CNM]}});hljs.registerLanguage("julia-repl",function(a){return{c:[{cN:"meta",b:/^julia>/,r:10,starts:{e:/^(?![ ]{6})/,sL:"julia"},aliases:["jldoctest"]}]}});hljs.registerLanguage("mercury",function(e){var i={keyword:"module use_module import_module include_module end_module initialise mutable initialize finalize finalise interface implementation pred mode func type inst solver any_pred any_func is semidet det nondet multi erroneous failure cc_nondet cc_multi typeclass instance where pragma promise external trace atomic or_else require_complete_switch require_det require_semidet require_multi require_nondet require_cc_multi require_cc_nondet require_erroneous require_failure",meta:"inline no_inline type_spec source_file fact_table obsolete memo loop_check minimal_model terminates does_not_terminate check_termination promise_equivalent_clauses foreign_proc foreign_decl foreign_code foreign_type foreign_import_module foreign_export_enum foreign_export foreign_enum may_call_mercury will_not_call_mercury thread_safe not_thread_safe maybe_thread_safe promise_pure promise_semipure tabled_for_io local untrailed trailed attach_to_io_state can_pass_as_mercury_type stable will_not_throw_exception may_modify_trail will_not_modify_trail may_duplicate may_not_duplicate affects_liveness does_not_affect_liveness doesnt_affect_liveness no_sharing unknown_sharing sharing",built_in:"some all not if then else true fail false try catch catch_any semidet_true semidet_false semidet_fail impure_true impure semipure"},r=e.C("%","$"),t={cN:"number",b:"0'.\\|0[box][0-9a-fA-F]*"},_=e.inherit(e.ASM,{r:0}),n=e.inherit(e.QSM,{r:0}),a={cN:"subst",b:"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]",r:0};n.c.push(a);var o={cN:"built_in",v:[{b:"<=>"},{b:"<=",r:0},{b:"=>",r:0},{b:"/\\\\"},{b:"\\\\/"}]},l={cN:"built_in",v:[{b:":-\\|-->"},{b:"=",r:0}]};return{aliases:["m","moo"],k:i,c:[o,l,r,e.CBCM,t,e.NM,_,n,{b:/:-/}]}});hljs.registerLanguage("verilog",function(e){var n={keyword:"accept_on alias always always_comb always_ff always_latch and assert assign assume automatic before begin bind bins binsof bit break buf|0 bufif0 bufif1 byte case casex casez cell chandle checker class clocking cmos config const constraint context continue cover covergroup coverpoint cross deassign default defparam design disable dist do edge else end endcase endchecker endclass endclocking endconfig endfunction endgenerate endgroup endinterface endmodule endpackage endprimitive endprogram endproperty endspecify endsequence endtable endtask enum event eventually expect export extends extern final first_match for force foreach forever fork forkjoin function generate|5 genvar global highz0 highz1 if iff ifnone ignore_bins illegal_bins implements implies import incdir include initial inout input inside instance int integer interconnect interface intersect join join_any join_none large let liblist library local localparam logic longint macromodule matches medium modport module nand negedge nettype new nexttime nmos nor noshowcancelled not notif0 notif1 or output package packed parameter pmos posedge primitive priority program property protected pull0 pull1 pulldown pullup pulsestyle_ondetect pulsestyle_onevent pure rand randc randcase randsequence rcmos real realtime ref reg reject_on release repeat restrict return rnmos rpmos rtran rtranif0 rtranif1 s_always s_eventually s_nexttime s_until s_until_with scalared sequence shortint shortreal showcancelled signed small soft solve specify specparam static string strong strong0 strong1 struct super supply0 supply1 sync_accept_on sync_reject_on table tagged task this throughout time timeprecision timeunit tran tranif0 tranif1 tri tri0 tri1 triand trior trireg type typedef union unique unique0 unsigned until until_with untyped use uwire var vectored virtual void wait wait_order wand weak weak0 weak1 while wildcard wire with within wor xnor xor",literal:"null",built_in:"$finish $stop $exit $fatal $error $warning $info $realtime $time $printtimescale $bitstoreal $bitstoshortreal $itor $signed $cast $bits $stime $timeformat $realtobits $shortrealtobits $rtoi $unsigned $asserton $assertkill $assertpasson $assertfailon $assertnonvacuouson $assertoff $assertcontrol $assertpassoff $assertfailoff $assertvacuousoff $isunbounded $sampled $fell $changed $past_gclk $fell_gclk $changed_gclk $rising_gclk $steady_gclk $coverage_control $coverage_get $coverage_save $set_coverage_db_name $rose $stable $past $rose_gclk $stable_gclk $future_gclk $falling_gclk $changing_gclk $display $coverage_get_max $coverage_merge $get_coverage $load_coverage_db $typename $unpacked_dimensions $left $low $increment $clog2 $ln $log10 $exp $sqrt $pow $floor $ceil $sin $cos $tan $countbits $onehot $isunknown $fatal $warning $dimensions $right $high $size $asin $acos $atan $atan2 $hypot $sinh $cosh $tanh $asinh $acosh $atanh $countones $onehot0 $error $info $random $dist_chi_square $dist_erlang $dist_exponential $dist_normal $dist_poisson $dist_t $dist_uniform $q_initialize $q_remove $q_exam $async$and$array $async$nand$array $async$or$array $async$nor$array $sync$and$array $sync$nand$array $sync$or$array $sync$nor$array $q_add $q_full $psprintf $async$and$plane $async$nand$plane $async$or$plane $async$nor$plane $sync$and$plane $sync$nand$plane $sync$or$plane $sync$nor$plane $system $display $displayb $displayh $displayo $strobe $strobeb $strobeh $strobeo $write $readmemb $readmemh $writememh $value$plusargs $dumpvars $dumpon $dumplimit $dumpports $dumpportson $dumpportslimit $writeb $writeh $writeo $monitor $monitorb $monitorh $monitoro $writememb $dumpfile $dumpoff $dumpall $dumpflush $dumpportsoff $dumpportsall $dumpportsflush $fclose $fdisplay $fdisplayb $fdisplayh $fdisplayo $fstrobe $fstrobeb $fstrobeh $fstrobeo $swrite $swriteb $swriteh $swriteo $fscanf $fread $fseek $fflush $feof $fopen $fwrite $fwriteb $fwriteh $fwriteo $fmonitor $fmonitorb $fmonitorh $fmonitoro $sformat $sformatf $fgetc $ungetc $fgets $sscanf $rewind $ftell $ferror"};return{aliases:["v","sv","svh"],cI:!1,k:n,l:/[\w\$]+/,c:[e.CBCM,e.CLCM,e.QSM,{cN:"number",c:[e.BE],v:[{b:"\\b((\\d+'(b|h|o|d|B|H|O|D))[0-9xzXZa-fA-F_]+)"},{b:"\\B(('(b|h|o|d|B|H|O|D))[0-9xzXZa-fA-F_]+)"},{b:"\\b([0-9_])+",r:0}]},{cN:"variable",v:[{b:"#\\((?!parameter).+\\)"},{b:"\\.\\w+",r:0}]},{cN:"meta",b:"`",e:"$",k:{"meta-keyword":"define __FILE__ __LINE__ begin_keywords celldefine default_nettype define else elsif end_keywords endcelldefine endif ifdef ifndef include line nounconnected_drive pragma resetall timescale unconnected_drive undef undefineall"},r:0}]}});hljs.registerLanguage("xl",function(e){var t="ObjectLoader Animate MovieCredits Slides Filters Shading Materials LensFlare Mapping VLCAudioVideo StereoDecoder PointCloud NetworkAccess RemoteControl RegExp ChromaKey Snowfall NodeJS Speech Charts",o={keyword:"if then else do while until for loop import with is as where when by data constant integer real text name boolean symbol infix prefix postfix block tree",literal:"true false nil",built_in:"in mod rem and or xor not abs sign floor ceil sqrt sin cos tan asin acos atan exp expm1 log log2 log10 log1p pi at text_length text_range text_find text_replace contains page slide basic_slide title_slide title subtitle fade_in fade_out fade_at clear_color color line_color line_width texture_wrap texture_transform texture scale_?x scale_?y scale_?z? translate_?x translate_?y translate_?z? rotate_?x rotate_?y rotate_?z? rectangle circle ellipse sphere path line_to move_to quad_to curve_to theme background contents locally time mouse_?x mouse_?y mouse_buttons "+t},a={cN:"string",b:'"',e:'"',i:"\\n"},r={cN:"string",b:"'",e:"'",i:"\\n"},i={cN:"string",b:"<<",e:">>"},l={cN:"number",b:"[0-9]+#[0-9A-Z_]+(\\.[0-9-A-Z_]+)?#?([Ee][+-]?[0-9]+)?"},n={bK:"import",e:"$",k:o,c:[a]},s={cN:"function",b:/[a-z][^\n]*->/,rB:!0,e:/->/,c:[e.inherit(e.TM,{starts:{eW:!0,k:o}})]};return{aliases:["tao"],l:/[a-zA-Z][a-zA-Z0-9_?]*/,k:o,c:[e.CLCM,e.CBCM,a,r,i,s,n,l,e.NM]}});hljs.registerLanguage("groovy",function(e){return{k:{literal:"true false null",keyword:"byte short char int long boolean float double void def as in assert trait super this abstract static volatile transient public private protected synchronized final class interface enum if else for while switch case break default continue throw throws try catch finally implements extends new import package return instanceof"},c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,{cN:"string",b:'"""',e:'"""'},{cN:"string",b:"'''",e:"'''"},{cN:"string",b:"\\$/",e:"/\\$",r:10},e.ASM,{cN:"regexp",b:/~?\/[^\/\n]+\//,c:[e.BE]},e.QSM,{cN:"meta",b:"^#!/usr/bin/env",e:"$",i:"\n"},e.BNM,{cN:"class",bK:"class interface trait enum",e:"{",i:":",c:[{bK:"extends implements"},e.UTM]},e.CNM,{cN:"meta",b:"@[A-Za-z]+"},{cN:"string",b:/[^\?]{0}[A-Za-z0-9_$]+ *:/},{b:/\?/,e:/\:/},{cN:"symbol",b:"^\\s*[A-Za-z0-9_$]+:",r:0}],i:/#|<\//}});hljs.registerLanguage("abnf",function(e){var r={ruleDeclaration:"^[a-zA-Z][a-zA-Z0-9-]*",unexpectedChars:"[!@#$^&',?+~`|:]"},a=["ALPHA","BIT","CHAR","CR","CRLF","CTL","DIGIT","DQUOTE","HEXDIG","HTAB","LF","LWSP","OCTET","SP","VCHAR","WSP"],b=e.C(";","$"),c={cN:"symbol",b:/%b[0-1]+(-[0-1]+|(\.[0-1]+)+){0,1}/},l={cN:"symbol",b:/%d[0-9]+(-[0-9]+|(\.[0-9]+)+){0,1}/},n={cN:"symbol",b:/%x[0-9A-F]+(-[0-9A-F]+|(\.[0-9A-F]+)+){0,1}/},t={cN:"symbol",b:/%[si]/},s={b:r.ruleDeclaration+"\\s*=",rB:!0,e:/=/,r:0,c:[{cN:"attribute",b:r.ruleDeclaration}]};return{i:r.unexpectedChars,k:a.join(" "),c:[s,b,c,l,n,t,e.QSM,e.NM]}});hljs.registerLanguage("gams",function(e){var a={keyword:"abort acronym acronyms alias all and assign binary card diag display else eq file files for free ge gt if integer le loop lt maximizing minimizing model models ne negative no not option options or ord positive prod put putpage puttl repeat sameas semicont semiint smax smin solve sos1 sos2 sum system table then until using while xor yes",literal:"eps inf na","built-in":"abs arccos arcsin arctan arctan2 Beta betaReg binomial ceil centropy cos cosh cvPower div div0 eDist entropy errorf execSeed exp fact floor frac gamma gammaReg log logBeta logGamma log10 log2 mapVal max min mod ncpCM ncpF ncpVUpow ncpVUsin normal pi poly power randBinomial randLinear randTriangle round rPower sigmoid sign signPower sin sinh slexp sllog10 slrec sqexp sqlog10 sqr sqrec sqrt tan tanh trunc uniform uniformInt vcPower bool_and bool_eqv bool_imp bool_not bool_or bool_xor ifThen rel_eq rel_ge rel_gt rel_le rel_lt rel_ne gday gdow ghour gleap gmillisec gminute gmonth gsecond gyear jdate jnow jstart jtime errorLevel execError gamsRelease gamsVersion handleCollect handleDelete handleStatus handleSubmit heapFree heapLimit heapSize jobHandle jobKill jobStatus jobTerminate licenseLevel licenseStatus maxExecError sleep timeClose timeComp timeElapsed timeExec timeStart"},o={cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0},r={cN:"symbol",v:[{b:/\=[lgenxc]=/},{b:/\$/}]},t={cN:"comment",v:[{b:"'",e:"'"},{b:'"',e:'"'}],i:"\\n",c:[e.BE]},i={b:"/",e:"/",k:a,c:[t,e.CLCM,e.CBCM,e.QSM,e.ASM,e.CNM]},l={b:/[a-z][a-z0-9_]*(\([a-z0-9_, ]*\))?[ \t]+/,eB:!0,e:"$",eW:!0,c:[t,i,{cN:"comment",b:/([ ]*[a-z0-9&#*=?@>\\<:\-,()$\[\]_.{}!+%^]+)+/,r:0}]};return{aliases:["gms"],cI:!0,k:a,c:[e.C(/^\$ontext/,/^\$offtext/),{cN:"meta",b:"^\\$[a-z0-9]+",e:"$",rB:!0,c:[{cN:"meta-keyword",b:"^\\$[a-z0-9]+"}]},e.C("^\\*","$"),e.CLCM,e.CBCM,e.QSM,e.ASM,{bK:"set sets parameter parameters variable variables scalar scalars equation equations",e:";",c:[e.C("^\\*","$"),e.CLCM,e.CBCM,e.QSM,e.ASM,i,l]},{bK:"table",e:";",rB:!0,c:[{bK:"table",e:"$",c:[l]},e.C("^\\*","$"),e.CLCM,e.CBCM,e.QSM,e.ASM,e.CNM]},{cN:"function",b:/^[a-z][a-z0-9_,\-+' ()$]+\.{2}/,rB:!0,c:[{cN:"title",b:/^[a-z0-9_]+/},o,r]},e.CNM,r]}});hljs.registerLanguage("makefile",function(e){var i={cN:"variable",v:[{b:"\\$\\("+e.UIR+"\\)",c:[e.BE]},{b:/\$[@%)?",r="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",s="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",c={cN:"number",b:s,r:0};return{aliases:["jsp"],k:r,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},c,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}});hljs.registerLanguage("apache",function(e){var r={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"section",b:""},{cN:"attribute",b:/\w+/,r:0,k:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"meta",b:"\\s\\[",e:"\\]$"},{cN:"variable",b:"[\\$%]\\{",e:"\\}",c:["self",r]},r,e.QSM]}}],i:/\S/}});hljs.registerLanguage("monkey",function(e){var n={cN:"number",r:0,v:[{b:"[$][a-fA-F0-9]+"},e.NM]};return{cI:!0,k:{keyword:"public private property continue exit extern new try catch eachin not abstract final select case default const local global field end if then else elseif endif while wend repeat until forever for to step next return module inline throw import",built_in:"DebugLog DebugStop Error Print ACos ACosr ASin ASinr ATan ATan2 ATan2r ATanr Abs Abs Ceil Clamp Clamp Cos Cosr Exp Floor Log Max Max Min Min Pow Sgn Sgn Sin Sinr Sqrt Tan Tanr Seed PI HALFPI TWOPI",literal:"true false null and or shl shr mod"},i:/\/\*/,c:[e.C("#rem","#end"),e.C("'","$",{r:0}),{cN:"function",bK:"function method",e:"[(=:]|$",i:/\n/,c:[e.UTM]},{cN:"class",bK:"class interface",e:"$",c:[{bK:"extends implements"},e.UTM]},{cN:"built_in",b:"\\b(self|super)\\b"},{cN:"meta",b:"\\s*#",e:"$",k:{"meta-keyword":"if else elseif endif end then"}},{cN:"meta",b:"^\\s*strict\\b"},{bK:"alias",e:"=",c:[e.UTM]},e.QSM,n]}});hljs.registerLanguage("openscad",function(e){var r={cN:"keyword",b:"\\$(f[asn]|t|vp[rtd]|children)"},n={cN:"literal",b:"false|true|PI|undef"},o={cN:"number",b:"\\b\\d+(\\.\\d+)?(e-?\\d+)?",r:0},i=e.inherit(e.QSM,{i:null}),t={cN:"meta",k:{"meta-keyword":"include use"},b:"include|use <",e:">"},s={cN:"params",b:"\\(",e:"\\)",c:["self",o,i,r,n]},c={b:"[*!#%]",r:0},a={cN:"function",bK:"module function",e:"\\=|\\{",c:[s,e.UTM]};return{aliases:["scad"],k:{keyword:"function module include use for intersection_for if else \\%",literal:"false true PI undef",built_in:"circle square polygon text sphere cube cylinder polyhedron translate rotate scale resize mirror multmatrix color offset hull minkowski union difference intersection abs sign sin cos tan acos asin atan atan2 floor round ceil ln log pow sqrt exp rands min max concat lookup str chr search version version_num norm cross parent_module echo import import_dxf dxf_linear_extrude linear_extrude rotate_extrude surface projection render children dxf_cross dxf_dim let assign"},c:[e.CLCM,e.CBCM,o,t,i,r,c,a]}});hljs.registerLanguage("scala",function(e){var t={cN:"meta",b:"@[A-Za-z]+"},a={cN:"subst",v:[{b:"\\$[A-Za-z0-9_]+"},{b:"\\${",e:"}"}]},r={cN:"string",v:[{b:'"',e:'"',i:"\\n",c:[e.BE]},{b:'"""',e:'"""',r:10},{b:'[a-z]+"',e:'"',i:"\\n",c:[e.BE,a]},{cN:"string",b:'[a-z]+"""',e:'"""',c:[a],r:10}]},c={cN:"symbol",b:"'\\w[\\w\\d_]*(?!')"},i={cN:"type",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},s={cN:"title",b:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,r:0},n={cN:"class",bK:"class object trait type",e:/[:={\[\n;]/,eE:!0,c:[{bK:"extends with",r:10},{b:/\[/,e:/\]/,eB:!0,eE:!0,r:0,c:[i]},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,r:0,c:[i]},s]},l={cN:"function",bK:"def",e:/[:={\[(\n;]/,eE:!0,c:[s]};return{k:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},c:[e.CLCM,e.CBCM,r,c,i,l,n,e.CNM,t]}});hljs.registerLanguage("elixir",function(e){var r="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?",n="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",b="and false then defined module in return redo retry end for true self when next until do begin unless nil break not case cond alias while ensure or include use alias fn quote",c={cN:"subst",b:"#\\{",e:"}",l:r,k:b},a={cN:"string",c:[e.BE,c],v:[{b:/'/,e:/'/},{b:/"/,e:/"/}]},i={cN:"function",bK:"def defp defmacro",e:/\B\b/,c:[e.inherit(e.TM,{b:r,endsParent:!0})]},l=e.inherit(i,{cN:"class",bK:"defimpl defmodule defprotocol defrecord",e:/\bdo\b|$|;/}),s=[a,e.HCM,l,i,{cN:"symbol",b:":(?!\\s)",c:[a,{b:n}],r:0},{cN:"symbol",b:r+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"->"},{b:"("+e.RSR+")\\s*",c:[e.HCM,{cN:"regexp",i:"\\n",c:[e.BE,c],v:[{b:"/",e:"/[a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}],r:0}];return c.c=s,{l:r,k:b,c:s}});hljs.registerLanguage("stylus",function(e){var t={cN:"variable",b:"\\$"+e.IR},o={cN:"number",b:"#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})"},i=["charset","css","debug","extend","font-face","for","import","include","media","mixin","page","warn","while"],r=["after","before","first-letter","first-line","active","first-child","focus","hover","lang","link","visited"],n=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],a="[\\.\\s\\n\\[\\:,]",l=["align-content","align-items","align-self","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","auto","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","clip-path","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","font","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-variant-ligatures","font-weight","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inherit","initial","justify-content","left","letter-spacing","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marks","mask","max-height","max-width","min-height","min-width","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","perspective","perspective-origin","pointer-events","position","quotes","resize","right","tab-size","table-layout","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-indent","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","white-space","widows","width","word-break","word-spacing","word-wrap","z-index"],d=["\\?","(\\bReturn\\b)","(\\bEnd\\b)","(\\bend\\b)","(\\bdef\\b)",";","#\\s","\\*\\s","===\\s","\\|","%"];return{aliases:["styl"],cI:!1,k:"if else for in",i:"("+d.join("|")+")",c:[e.QSM,e.ASM,e.CLCM,e.CBCM,o,{b:"\\.[a-zA-Z][a-zA-Z0-9_-]*"+a,rB:!0,c:[{cN:"selector-class",b:"\\.[a-zA-Z][a-zA-Z0-9_-]*"}]},{b:"\\#[a-zA-Z][a-zA-Z0-9_-]*"+a,rB:!0,c:[{cN:"selector-id",b:"\\#[a-zA-Z][a-zA-Z0-9_-]*"}]},{b:"\\b("+n.join("|")+")"+a,rB:!0,c:[{cN:"selector-tag",b:"\\b[a-zA-Z][a-zA-Z0-9_-]*"}]},{b:"&?:?:\\b("+r.join("|")+")"+a},{b:"@("+i.join("|")+")\\b"},t,e.CSSNM,e.NM,{cN:"function",b:"^[a-zA-Z][a-zA-Z0-9_-]*\\(.*\\)",i:"[\\n]",rB:!0,c:[{cN:"title",b:"\\b[a-zA-Z][a-zA-Z0-9_-]*"},{cN:"params",b:/\(/,e:/\)/,c:[o,t,e.ASM,e.CSSNM,e.NM,e.QSM]}]},{cN:"attribute",b:"\\b("+l.reverse().join("|")+")\\b",starts:{e:/;|$/,c:[o,t,e.ASM,e.QSM,e.CSSNM,e.NM,e.CBCM],i:/\./,r:0}}]}});hljs.registerLanguage("d",function(e){var t={keyword:"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__",built_in:"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring",literal:"false null true"},r="(0|[1-9][\\d_]*)",a="(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)",i="0[bB][01_]+",n="([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)",_="0[xX]"+n,c="([eE][+-]?"+a+")",d="("+a+"(\\.\\d*|"+c+")|\\d+\\."+a+a+"|\\."+r+c+"?)",o="(0[xX]("+n+"\\."+n+"|\\.?"+n+")[pP][+-]?"+a+")",s="("+r+"|"+i+"|"+_+")",l="("+o+"|"+d+")",u="\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};",b={cN:"number",b:"\\b"+s+"(L|u|U|Lu|LU|uL|UL)?",r:0},f={cN:"number",b:"\\b("+l+"([fF]|L|i|[fF]i|Li)?|"+s+"(i|[fF]i|Li))",r:0},g={cN:"string",b:"'("+u+"|.)",e:"'",i:"."},h={b:u,r:0},p={cN:"string",b:'"',c:[h],e:'"[cwd]?'},m={cN:"string",b:'[rq]"',e:'"[cwd]?',r:5},w={cN:"string",b:"`",e:"`[cwd]?"},N={cN:"string",b:'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',r:10},A={cN:"string",b:'q"\\{',e:'\\}"'},F={cN:"meta",b:"^#!",e:"$",r:5},y={cN:"meta",b:"#(line)",e:"$",r:5},L={cN:"keyword",b:"@[a-zA-Z_][a-zA-Z_\\d]*"},v=e.C("\\/\\+","\\+\\/",{c:["self"],r:10});return{l:e.UIR,k:t,c:[e.CLCM,e.CBCM,v,N,p,m,w,A,f,b,g,F,y,L]}});hljs.registerLanguage("kotlin",function(e){var t={keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit initinterface annotation data sealed internal infix operator out by constructor super trait volatile transient native default",built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing",literal:"true false null"},r={cN:"keyword",b:/\b(break|continue|return|this)\b/,starts:{c:[{cN:"symbol",b:/@\w+/}]}},i={cN:"symbol",b:e.UIR+"@"},n={cN:"subst",b:"\\${",e:"}",c:[e.ASM,e.CNM]},a={cN:"variable",b:"\\$"+e.UIR},c={cN:"string",v:[{b:'"""',e:'"""',c:[a,n]},{b:"'",e:"'",i:/\n/,c:[e.BE]},{b:'"',e:'"',i:/\n/,c:[e.BE,a,n]}]},s={cN:"meta",b:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UIR+")?"},o={cN:"meta",b:"@"+e.UIR,c:[{b:/\(/,e:/\)/,c:[e.inherit(c,{cN:"meta-string"})]}]};return{k:t,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,r,i,s,o,{cN:"function",bK:"fun",e:"[(]|$",rB:!0,eE:!0,k:t,i:/fun\s+(<.*>)?[^\s\(]+(\s+[^\s\(]+)\s*=/,r:5,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"type",b://,k:"reified",r:0},{cN:"params",b:/\(/,e:/\)/,endsParent:!0,k:t,r:0,c:[{b:/:/,e:/[=,\/]/,eW:!0,c:[{cN:"type",b:e.UIR},e.CLCM,e.CBCM],r:0},e.CLCM,e.CBCM,s,o,c,e.CNM]},e.CBCM]},{cN:"class",bK:"class interface trait",e:/[:\{(]|$/,eE:!0,i:"extends implements",c:[{bK:"public protected internal private constructor"},e.UTM,{cN:"type",b://,eB:!0,eE:!0,r:0},{cN:"type",b:/[,:]\s*/,e:/[<\(,]|$/,eB:!0,rE:!0},s,o]},c,{cN:"meta",b:"^#!/usr/bin/env",e:"$",i:"\n"},e.CNM]}}); \ No newline at end of file diff --git a/src/utils/highlightjs/highlightjs-line-numbers.min.js b/src/utils/highlightjs/highlightjs-line-numbers.min.js deleted file mode 100644 index 2699f8a3..00000000 --- a/src/utils/highlightjs/highlightjs-line-numbers.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e){"use strict";function t(){var e=document.createElement("style");e.type="text/css",e.innerHTML=".{0}{border-collapse:collapse}.{0} td{padding:0}.{1}:before{content:attr({2})}".format(s,d,u),document.getElementsByTagName("head")[0].appendChild(e)}function n(){"complete"===document.readyState?r():e.addEventListener("DOMContentLoaded",r)}function r(){try{var e=document.querySelectorAll("code.hljs");for(var t in e)e.hasOwnProperty(t)&&o(e[t])}catch(n){console.error("LineNumbers error: ",n)}}function o(e){if("object"==typeof e){var t=l(e.innerHTML);if(t.length>1){for(var n="",r=0;r
    {6}
    '.format(c,a,d,u,i,r+1,t[r].length>0?t[r]:" ");e.innerHTML='{1}
    '.format(s,n)}}}function l(e){return 0===e.length?[]:e.split(/\r\n|\r|\n/g)}var s="hljs-ln",a="hljs-ln-line",i="hljs-ln-code",c="hljs-ln-numbers",d="hljs-ln-n",u="data-line-number";String.prototype.format=String.prototype.f=function(){var e=arguments;return this.replace(/\{(\d+)\}/g,function(t,n){return e[n]?e[n]:t})},"undefined"==typeof e.hljs?console.error("highlight.js not detected!"):(e.hljs.initLineNumbersOnLoad=n,e.hljs.lineNumbersBlock=o,t())}(window); \ No newline at end of file diff --git a/src/utils/markdown-it/README.md b/src/utils/markdown-it/README.md deleted file mode 100644 index bc60824c..00000000 --- a/src/utils/markdown-it/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# [markdown-it](https://github.com/markdown-it/markdown-it) -v8.3.1 -Alex Kocharin -Vitaly Puzrin - -# [markdown-it-headinganchor](https://github.com/adam-p/markdown-it-headinganchor) -v1.3.0 -Adam Pritchard -Modified by Le Tan - -# [markdown-it-task-lists](https://github.com/revin/markdown-it-task-lists) -v1.4.0 -Revin Guillen diff --git a/src/utils/markdown-it/markdown-it-footnote.min.js b/src/utils/markdown-it/markdown-it-footnote.min.js deleted file mode 100644 index d0271179..00000000 --- a/src/utils/markdown-it/markdown-it-footnote.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! markdown-it-footnote 3.0.1 https://github.com//markdown-it/markdown-it-footnote @license MIT */ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var o;o="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,o.markdownitFootnote=e()}}(function(){return function e(o,t,n){function r(f,l){if(!t[f]){if(!o[f]){var u="function"==typeof require&&require;if(!l&&u)return u(f,!0);if(s)return s(f,!0);var i=new Error("Cannot find module '"+f+"'");throw i.code="MODULE_NOT_FOUND",i}var a=t[f]={exports:{}};o[f][0].call(a.exports,function(e){var t=o[f][1][e];return r(t?t:e)},a,a.exports,e,o,t,n)}return t[f].exports}for(var s="function"==typeof require&&require,f=0;f0&&(t+=":"+e[o].meta.subId),"["+t+"]"}function s(e,o,t,n,r){var s=r.rules.footnote_anchor_name(e,o,t,n,r),f=r.rules.footnote_caption(e,o,t,n,r),l=s;return e[o].meta.subId>0&&(l+=":"+e[o].meta.subId),''+f+""}function f(e,o,t){return(t.xhtmlOut?'
    \n':'
    \n')+'
    \n
      \n'}function l(){return"
    \n
    \n"}function u(e,o,t,n,r){var s=r.rules.footnote_anchor_name(e,o,t,n,r);return e[o].meta.subId>0&&(s+=":"+e[o].meta.subId),'
  • '}function i(){return"
  • \n"}function a(e,o,t,n,r){var s=r.rules.footnote_anchor_name(e,o,t,n,r);return e[o].meta.subId>0&&(s+=":"+e[o].meta.subId),' \u21a9\ufe0e'}o.exports=function(e){function o(e,o,t,n){var r,s,f,l,u,i,a,c,p,d,k,b=e.bMarks[o]+e.tShift[o],v=e.eMarks[o];if(b+4>v)return!1;if(91!==e.src.charCodeAt(b))return!1;if(94!==e.src.charCodeAt(b+1))return!1;for(u=b+2;u=v||58!==e.src.charCodeAt(++u))return!1;if(n)return!0;for(u++,e.env.footnotes||(e.env.footnotes={}),e.env.footnotes.refs||(e.env.footnotes.refs={}),i=e.src.slice(b+2,u-2),e.env.footnotes.refs[":"+i]=-1,a=new e.Token("footnote_reference_open","",1),a.meta={label:i},a.level=e.level++,e.tokens.push(a),r=e.bMarks[o],s=e.tShift[o],f=e.sCount[o],l=e.parentType,k=u,c=p=e.sCount[o]+u-(e.bMarks[o]+e.tShift[o]);u=l)&&(94===e.src.charCodeAt(u)&&(91===e.src.charCodeAt(u+1)&&(t=u+2,n=d(e,u+1),!(n<0)&&(o||(e.env.footnotes||(e.env.footnotes={}),e.env.footnotes.list||(e.env.footnotes.list=[]),r=e.env.footnotes.list.length,e.md.inline.parse(e.src.slice(t,n),e.md,e.env,f=[]),s=e.push("footnote_ref","",0),s.meta={id:r},e.env.footnotes.list[r]={tokens:f}),e.pos=n+1,e.posMax=l,!0))))}function c(e,o){var t,n,r,s,f,l=e.posMax,u=e.pos;if(u+3>l)return!1;if(!e.env.footnotes||!e.env.footnotes.refs)return!1;if(91!==e.src.charCodeAt(u))return!1;if(94!==e.src.charCodeAt(u+1))return!1;for(n=u+2;n=l)&&(n++,t=e.src.slice(u+2,n-1),"undefined"!=typeof e.env.footnotes.refs[":"+t]&&(o||(e.env.footnotes.list||(e.env.footnotes.list=[]),e.env.footnotes.refs[":"+t]<0?(r=e.env.footnotes.list.length,e.env.footnotes.list[r]={label:t,count:0},e.env.footnotes.refs[":"+t]=r):r=e.env.footnotes.refs[":"+t],s=e.env.footnotes.list[r].count,e.env.footnotes.list[r].count++,f=e.push("footnote_ref","",0),f.meta={id:r,subId:s,label:t}),e.pos=n,e.posMax=l,!0)))}function p(e){var o,t,n,r,s,f,l,u,i,a,c=!1,p={};if(e.env.footnotes&&(e.tokens=e.tokens.filter(function(e){return"footnote_reference_open"===e.type?(c=!0,i=[],a=e.meta.label,!1):"footnote_reference_close"===e.type?(c=!1,p[":"+a]=i,!1):(c&&i.push(e),!c)}),e.env.footnotes.list)){for(f=e.env.footnotes.list,l=new e.Token("footnote_block_open","",1),e.tokens.push(l),o=0,t=f.length;o0?f[o].count:1,n=0;n'; - - headingInlineToken.children.unshift(anchorToken); - } - - // Advance past the inline and heading_close tokens. - i += 2; - } - }; -} - -module.exports = function headinganchor_plugin(md, opts) { - var defaults = { - anchorClass: 'markdown-it-headinganchor', - addHeadingID: true, - addHeadingAnchor: true, - // Added by Le Tan (github.com/tamlok) - slugify: slugify, - headingHook: function(openToken, inlineToken, anchor) {} - }; - var options = md.utils.assign(defaults, opts); - md.core.ruler.push('heading_anchors', makeRule(md, options)); -}; - -},{}]},{},[1])(1) -}); diff --git a/src/utils/markdown-it/markdown-it-sub.min.js b/src/utils/markdown-it/markdown-it-sub.min.js deleted file mode 100644 index a3a4542f..00000000 --- a/src/utils/markdown-it/markdown-it-sub.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! markdown-it-sub 1.0.0 https://github.com//markdown-it/markdown-it-sub @license MIT */ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.markdownitSub=e()}}(function(){return function e(r,o,n){function t(i,u){if(!o[i]){if(!r[i]){var f="function"==typeof require&&require;if(!u&&f)return f(i,!0);if(s)return s(i,!0);var p=new Error("Cannot find module '"+i+"'");throw p.code="MODULE_NOT_FOUND",p}var a=o[i]={exports:{}};r[i][0].call(a.exports,function(e){var o=r[i][1][e];return t(o?o:e)},a,a.exports,e,r,o,n)}return o[i].exports}for(var s="function"==typeof require&&require,i=0;i=i)return!1;for(e.pos=u+1;e.pos?@[\]^_`{|}~-])/g;r.exports=function(e){e.inline.ruler.after("emphasis","sub",o)}},{}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/utils/markdown-it/markdown-it-sup.min.js b/src/utils/markdown-it/markdown-it-sup.min.js deleted file mode 100644 index 67da65cd..00000000 --- a/src/utils/markdown-it/markdown-it-sup.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! markdown-it-sup 1.0.0 https://github.com//markdown-it/markdown-it-sup @license MIT */ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.markdownitSup=e()}}(function(){return function e(r,o,n){function t(i,p){if(!o[i]){if(!r[i]){var u="function"==typeof require&&require;if(!p&&u)return u(i,!0);if(s)return s(i,!0);var f=new Error("Cannot find module '"+i+"'");throw f.code="MODULE_NOT_FOUND",f}var a=o[i]={exports:{}};r[i][0].call(a.exports,function(e){var o=r[i][1][e];return t(o?o:e)},a,a.exports,e,r,o,n)}return o[i].exports}for(var s="function"==typeof require&&require,i=0;i=i)return!1;for(e.pos=p+1;e.pos?@[\]^_`{|}~-])/g;r.exports=function(e){e.inline.ruler.after("emphasis","sup",o)}},{}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/utils/markdown-it/markdown-it-task-lists.min.js b/src/utils/markdown-it/markdown-it-task-lists.min.js deleted file mode 100644 index 6a3f81a7..00000000 --- a/src/utils/markdown-it/markdown-it-task-lists.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! markdown-it-task-lists 1.4.0 https://github.com/revin/markdown-it-task-lists#readme by @license {ISC} */ -!function(n){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define([],n);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.markdownitTaskLists=n()}}(function(){return function n(e,t,i){function r(c,f){if(!t[c]){if(!e[c]){var u="function"==typeof require&&require;if(!f&&u)return u(c,!0);if(o)return o(c,!0);var l=new Error("Cannot find module '"+c+"'");throw l.code="MODULE_NOT_FOUND",l}var s=t[c]={exports:{}};e[c][0].call(s.exports,function(n){var t=e[c][1][n];return r(t?t:n)},s,s.exports,n,e,t,i)}return t[c].exports}for(var o="function"==typeof require&&require,c=0;ci?n.attrPush(r):n.attrs[i]=r}function r(n,e){for(var t=n[e].level-1,i=e-1;i>=0;i--)if(n[i].level===t)return i;return-1}function o(n,e){return s(n[e])&&a(n[e-1])&&d(n[e-2])&&p(n[e])}function c(n,e){n.children.unshift(f(n,e)),n.children[1].content=n.children[1].content.slice(3),n.content=n.content.slice(3),x&&(n.children.unshift(u(e)),n.children.push(l(e)))}function f(n,e){var t=new e("html_inline","",0),i=h?' disabled="" ':"";return 0===n.content.indexOf("[ ]")?t.content='':(0===n.content.indexOf("[x]")||0===n.content.indexOf("[X]"))&&(t.content=''),t}function u(n){var e=new n("html_inline","",0);return e.content="",e}function s(n){return"inline"===n.type}function a(n){return"paragraph_open"===n.type}function d(n){return"list_item_open"===n.type}function p(n){return 0===n.content.indexOf("[ ]")||0===n.content.indexOf("[x]")||0===n.content.indexOf("[X]")}var h=!0,x=!1;e.exports=function(n,e){e&&(h=!e.enabled,x=!!e.label),n.core.ruler.after("inline","github-task-lists",function(n){for(var e=n.tokens,t=2;t`\\x00-\\x20]+|'[^']*'|\"[^\"]*\"))?)*\\s*\\/?>",s="<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>",o=new RegExp("^(?:"+n+"|"+s+"|||<[?].*?[?]>|]*>|)"),i=new RegExp("^(?:"+n+"|"+s+")");r.exports.HTML_TAG_RE=o,r.exports.HTML_OPEN_CLOSE_TAG_RE=i},{}],4:[function(e,r,t){"use strict";function n(e){return Object.prototype.toString.call(e)}function s(e){return"[object String]"===n(e)}function o(e,r){return y.call(e,r)}function i(e){return Array.prototype.slice.call(arguments,1).forEach(function(r){if(r){if("object"!=typeof r)throw new TypeError(r+"must be object");Object.keys(r).forEach(function(t){e[t]=r[t]})}}),e}function a(e,r,t){return[].concat(e.slice(0,r),t,e.slice(r+1))}function c(e){return!(e>=55296&&e<=57343)&&(!(e>=64976&&e<=65007)&&(65535!=(65535&e)&&65534!=(65535&e)&&(!(e>=0&&e<=8)&&(11!==e&&(!(e>=14&&e<=31)&&(!(e>=127&&e<=159)&&!(e>1114111)))))))}function l(e){if(e>65535){e-=65536;var r=55296+(e>>10),t=56320+(1023&e);return String.fromCharCode(r,t)}return String.fromCharCode(e)}function u(e,r){var t=0;return o(w,r)?w[r]:35===r.charCodeAt(0)&&A.test(r)&&(t="x"===r[1].toLowerCase()?parseInt(r.slice(2),16):parseInt(r.slice(1),10),c(t))?l(t):e}function p(e){return e.indexOf("\\")<0?e:e.replace(x,"$1")}function h(e){return e.indexOf("\\")<0&&e.indexOf("&")<0?e:e.replace(C,function(e,r,t){return r?r:u(e,t)})}function f(e){return q[e]}function d(e){return D.test(e)?e.replace(/[&<>"]/g,f):e}function m(e){return e.replace(/[.?*+^$[\]\\(){}|-]/g,"\\$&")}function _(e){switch(e){case 9:case 32:return!0}return!1}function g(e){if(e>=8192&&e<=8202)return!0;switch(e){case 9:case 10:case 11:case 12:case 13:case 32:case 160:case 5760:case 8239:case 8287:case 12288:return!0}return!1}function b(e){return E.test(e)}function k(e){switch(e){case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 58:case 59:case 60:case 61:case 62:case 63:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 124:case 125:case 126:return!0;default:return!1}}function v(e){return e.trim().replace(/\s+/g," ").toUpperCase()}var y=Object.prototype.hasOwnProperty,x=/\\([!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~])/g,C=new RegExp(x.source+"|"+/&([a-z#][a-z0-9]{1,31});/gi.source,"gi"),A=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i,w=e("./entities"),D=/[&<>"]/,q={"&":"&","<":"<",">":">",'"':"""},E=e("uc.micro/categories/P/regex");t.lib={},t.lib.mdurl=e("mdurl"),t.lib.ucmicro=e("uc.micro"),t.assign=i,t.isString=s,t.has=o,t.unescapeMd=p,t.unescapeAll=h,t.isValidEntityCode=c,t.fromCodePoint=l,t.escapeHtml=d,t.arrayReplaceAt=a,t.isSpace=_,t.isWhiteSpace=g,t.isMdAsciiPunct=k,t.isPunctChar=b,t.escapeRE=m,t.normalizeReference=v},{"./entities":1,mdurl:58,"uc.micro":65,"uc.micro/categories/P/regex":63}],5:[function(e,r,t){"use strict";t.parseLinkLabel=e("./parse_link_label"),t.parseLinkDestination=e("./parse_link_destination"),t.parseLinkTitle=e("./parse_link_title")},{"./parse_link_destination":6,"./parse_link_label":7,"./parse_link_title":8}],6:[function(e,r,t){"use strict";var n=e("../common/utils").isSpace,s=e("../common/utils").unescapeAll;r.exports=function(e,r,t){var o,i,a=r,c={ok:!1,pos:0,lines:0,str:""};if(60===e.charCodeAt(r)){for(r++;r1)break;if(41===o&&--i<0)break;r++}return a===r?c:(c.str=s(e.slice(a,r)),c.lines=0,c.pos=r,c.ok=!0,c)}},{"../common/utils":4}],7:[function(e,r,t){"use strict";r.exports=function(e,r,t){var n,s,o,i,a=-1,c=e.posMax,l=e.pos;for(e.pos=r+1,n=1;e.pos=t)return c;if(34!==(o=e.charCodeAt(r))&&39!==o&&40!==o)return c;for(r++,40===o&&(o=41);r=0))try{r.hostname=m.toASCII(r.hostname)}catch(e){}return d.encode(d.format(r))}function o(e){var r=d.parse(e,!0);if(r.hostname&&(!r.protocol||k.indexOf(r.protocol)>=0))try{r.hostname=m.toUnicode(r.hostname)}catch(e){}return d.decode(d.format(r))}function i(e,r){if(!(this instanceof i))return new i(e,r);r||a.isString(e)||(r=e||{},e="default"),this.inline=new h,this.block=new p,this.core=new u,this.renderer=new l,this.linkify=new f,this.validateLink=n,this.normalizeLink=s,this.normalizeLinkText=o,this.utils=a,this.helpers=a.assign({},c),this.options={},this.configure(e),r&&this.set(r)}var a=e("./common/utils"),c=e("./helpers"),l=e("./renderer"),u=e("./parser_core"),p=e("./parser_block"),h=e("./parser_inline"),f=e("linkify-it"),d=e("mdurl"),m=e("punycode"),_={default:e("./presets/default"),zero:e("./presets/zero"),commonmark:e("./presets/commonmark")},g=/^(vbscript|javascript|file|data):/,b=/^data:image\/(gif|png|jpeg|webp);/,k=["http:","https:","mailto:"];i.prototype.set=function(e){return a.assign(this.options,e),this},i.prototype.configure=function(e){var r,t=this;if(a.isString(e)&&(r=e,!(e=_[r])))throw new Error('Wrong `markdown-it` preset "'+r+'", check name');if(!e)throw new Error("Wrong `markdown-it` preset, can't be empty");return e.options&&t.set(e.options),e.components&&Object.keys(e.components).forEach(function(r){e.components[r].rules&&t[r].ruler.enableOnly(e.components[r].rules),e.components[r].rules2&&t[r].ruler2.enableOnly(e.components[r].rules2)}),this},i.prototype.enable=function(e,r){var t=[];Array.isArray(e)||(e=[e]),["core","block","inline"].forEach(function(r){t=t.concat(this[r].ruler.enable(e,!0))},this),t=t.concat(this.inline.ruler2.enable(e,!0));var n=e.filter(function(e){return t.indexOf(e)<0});if(n.length&&!r)throw new Error("MarkdownIt. Failed to enable unknown rule(s): "+n);return this},i.prototype.disable=function(e,r){var t=[];Array.isArray(e)||(e=[e]),["core","block","inline"].forEach(function(r){t=t.concat(this[r].ruler.disable(e,!0))},this),t=t.concat(this.inline.ruler2.disable(e,!0));var n=e.filter(function(e){return t.indexOf(e)<0});if(n.length&&!r)throw new Error("MarkdownIt. Failed to disable unknown rule(s): "+n);return this},i.prototype.use=function(e){var r=[this].concat(Array.prototype.slice.call(arguments,1));return e.apply(e,r),this},i.prototype.parse=function(e,r){if("string"!=typeof e)throw new Error("Input data should be a String");var t=new this.core.State(e,this,r);return this.core.process(t),t.tokens},i.prototype.render=function(e,r){return r=r||{},this.renderer.render(this.parse(e,r),this.options,r)},i.prototype.parseInline=function(e,r){var t=new this.core.State(e,this,r);return t.inlineMode=!0,this.core.process(t),t.tokens},i.prototype.renderInline=function(e,r){return r=r||{},this.renderer.render(this.parseInline(e,r),this.options,r)},r.exports=i},{"./common/utils":4,"./helpers":5,"./parser_block":10,"./parser_core":11,"./parser_inline":12,"./presets/commonmark":13,"./presets/default":14,"./presets/zero":15,"./renderer":16,"linkify-it":53,mdurl:58,punycode:60}],10:[function(e,r,t){"use strict";function n(){this.ruler=new s;for(var e=0;e=t))&&!(e.sCount[i]=c){e.line=t;break}for(n=0;n=o)break}else e.pending+=e.src[e.pos++]}e.pending&&e.pushPending()},n.prototype.parse=function(e,r,t,n){var s,o,i,a=new this.State(e,r,t,n);for(this.tokenize(a),o=this.ruler2.getRules(""),i=o.length,s=0;s"+i(e[r].content)+"
    "},a.code_block=function(e,r,t,n,s){var o=e[r];return""+i(e[r].content)+"
    \n"},a.fence=function(e,r,t,n,s){var a,c,l,u,p=e[r],h=p.info?o(p.info).trim():"",f="";return h&&(f=h.split(/\s+/g)[0]),a=t.highlight?t.highlight(p.content,f)||i(p.content):i(p.content),0===a.indexOf(""+a+"
    \n"):"
    "+a+"
    \n"},a.image=function(e,r,t,n,s){var o=e[r];return o.attrs[o.attrIndex("alt")][1]=s.renderInlineAsText(o.children,t,n),s.renderToken(e,r,t)},a.hardbreak=function(e,r,t){return t.xhtmlOut?"
    \n":"
    \n"},a.softbreak=function(e,r,t){return t.breaks?t.xhtmlOut?"
    \n":"
    \n":"\n"},a.text=function(e,r){return i(e[r].content)},a.html_block=function(e,r){return e[r].content},a.html_inline=function(e,r){return e[r].content},n.prototype.renderAttrs=function(e){var r,t,n;if(!e.attrs)return"";for(n="",r=0,t=e.attrs.length;r\n":">")},n.prototype.renderInline=function(e,r,t){for(var n,s="",o=this.rules,i=0,a=e.length;i=4)return!1;if(62!==e.src.charCodeAt(D++))return!1;if(s)return!0;for(c=d=e.sCount[r]+D-(e.bMarks[r]+e.tShift[r]),32===e.src.charCodeAt(D)?(D++,c++,d++,o=!1,y=!0):9===e.src.charCodeAt(D)?(y=!0,(e.bsCount[r]+d)%4==3?(D++,c++,d++,o=!1):o=!0):y=!1,m=[e.bMarks[r]],e.bMarks[r]=D;D=q,k=[e.sCount[r]],e.sCount[r]=d-c,v=[e.tShift[r]],e.tShift[r]=D-e.bMarks[r],C=e.md.block.ruler.getRules("blockquote"),b=e.parentType,e.parentType="blockquote",f=r+1;f=q));f++)if(62!==e.src.charCodeAt(D++)||l){if(p)break;for(x=!1,a=0,u=C.length;a=q,_.push(e.bsCount[f]),e.bsCount[f]=e.sCount[f]+1+(y?1:0),k.push(e.sCount[f]),e.sCount[f]=d-c,v.push(e.tShift[f]),e.tShift[f]=D-e.bMarks[f]}for(g=e.blkIndent,e.blkIndent=0,A=e.push("blockquote_open","blockquote",1),A.markup=">",A.map=h=[r,0],e.md.block.tokenize(e,r,f),A=e.push("blockquote_close","blockquote",-1),A.markup=">",e.lineMax=w,e.parentType=b,h[1]=e.line,a=0;a=4))break;n++,s=n}return e.line=s,o=e.push("code_block","code",0),o.content=e.getLines(r,s,4+e.blkIndent,!0),o.map=[r,e.line],!0}},{}],20:[function(e,r,t){"use strict";r.exports=function(e,r,t,n){var s,o,i,a,c,l,u,p=!1,h=e.bMarks[r]+e.tShift[r],f=e.eMarks[r];if(e.sCount[r]-e.blkIndent>=4)return!1;if(h+3>f)return!1;if(126!==(s=e.src.charCodeAt(h))&&96!==s)return!1;if(c=h,h=e.skipChars(h,s),(o=h-c)<3)return!1;if(u=e.src.slice(c,h),i=e.src.slice(h,f),i.indexOf(String.fromCharCode(s))>=0)return!1;if(n)return!0;for(a=r;!(++a>=t)&&(h=c=e.bMarks[a]+e.tShift[a],f=e.eMarks[a],!(h=4||(h=e.skipChars(h,s))-c=4)return!1;if(35!==(o=e.src.charCodeAt(l))||l>=u)return!1;for(i=1,o=e.src.charCodeAt(++l);35===o&&l6||ll&&n(e.src.charCodeAt(a-1))&&(u=a),e.line=r+1,c=e.push("heading_open","h"+String(i),1),c.markup="########".slice(0,i),c.map=[r,e.line],c=e.push("inline","",0),c.content=e.src.slice(l,u).trim(),c.map=[r,e.line],c.children=[],c=e.push("heading_close","h"+String(i),-1),c.markup="########".slice(0,i),!0))}},{"../common/utils":4}],22:[function(e,r,t){"use strict";var n=e("../common/utils").isSpace;r.exports=function(e,r,t,s){var o,i,a,c,l=e.bMarks[r]+e.tShift[r],u=e.eMarks[r];if(e.sCount[r]-e.blkIndent>=4)return!1;if(42!==(o=e.src.charCodeAt(l++))&&45!==o&&95!==o)return!1;for(i=1;l|$))/i,/<\/(script|pre|style)>/i,!0],[/^/,!0],[/^<\?/,/\?>/,!0],[/^/,!0],[/^/,!0],[new RegExp("^|$))","i"),/^$/,!0],[new RegExp(s.source+"\\s*$"),/^$/,!1]];r.exports=function(e,r,t,n){var s,i,a,c,l=e.bMarks[r]+e.tShift[r],u=e.eMarks[r];if(e.sCount[r]-e.blkIndent>=4)return!1;if(!e.md.options.html)return!1;if(60!==e.src.charCodeAt(l))return!1;for(c=e.src.slice(l,u),s=0;s=4)return!1;for(h=e.parentType,e.parentType="paragraph";f3)){if(e.sCount[f]>=e.blkIndent&&(c=e.bMarks[f]+e.tShift[f],l=e.eMarks[f],c=l))){u=61===p?1:2;break}if(!(e.sCount[f]<0)){for(s=!1,o=0,i=d.length;o=o)return-1;if((t=e.src.charCodeAt(s++))<48||t>57)return-1;for(;;){if(s>=o)return-1;t=e.src.charCodeAt(s++);{if(!(t>=48&&t<=57)){if(41===t||46===t)break;return-1}if(s-n>=10)return-1}}return s=4)return!1;if(a&&"paragraph"===e.parentType&&e.tShift[r]>=e.blkIndent&&(M=!0),(F=s(e,r))>=0){if(d=!0,z=e.bMarks[r]+e.tShift[r],v=Number(e.src.substr(z,F-z-1)),M&&1!==v)return!1}else{if(!((F=n(e,r))>=0))return!1;d=!1}if(M&&e.skipSpaces(F)>=e.eMarks[r])return!1;if(k=e.src.charCodeAt(F-1),a)return!0;for(b=e.tokens.length,d?(R=e.push("ordered_list_open","ol",1),1!==v&&(R.attrs=[["start",v]])):R=e.push("bullet_list_open","ul",1),R.map=g=[r,0],R.markup=String.fromCharCode(k),x=r,L=!1,I=e.md.block.ruler.getRules("list"),D=e.parentType,e.parentType="list";x=y?1:C-f,h>4&&(h=1),p=f+h,R=e.push("list_item_open","li",1),R.markup=String.fromCharCode(k),R.map=m=[r,0],A=e.blkIndent,E=e.tight,q=e.tShift[r],w=e.sCount[r],e.blkIndent=p,e.tight=!0,e.tShift[r]=l-e.bMarks[r],e.sCount[r]=C,l>=y&&e.isEmpty(r+1)?e.line=Math.min(e.line+2,t):e.md.block.tokenize(e,r,t,!0),e.tight&&!L||(B=!1),L=e.line-r>1&&e.isEmpty(e.line-1),e.blkIndent=A,e.tShift[r]=q,e.sCount[r]=w,e.tight=E,R=e.push("list_item_close","li",-1),R.markup=String.fromCharCode(k),x=r=e.line,m[1]=x,l=e.bMarks[r],x>=t)break;if(e.sCount[x]3||e.sCount[c]<0)){for(n=!1,s=0,o=l.length;s=4)return!1;if(91!==e.src.charCodeAt(C))return!1;for(;++C3||e.sCount[w]<0)){for(k=!1,p=0,h=v.length;p0&&this.level++,this.tokens.push(n),n},n.prototype.isEmpty=function(e){return this.bMarks[e]+this.tShift[e]>=this.eMarks[e]},n.prototype.skipEmptyLines=function(e){for(var r=this.lineMax;er;)if(!o(this.src.charCodeAt(--e)))return e+1;return e},n.prototype.skipChars=function(e,r){for(var t=this.src.length;et;)if(r!==this.src.charCodeAt(--e))return e+1;return e},n.prototype.getLines=function(e,r,t,n){var s,i,a,c,l,u,p,h=e;if(e>=r)return"";for(u=new Array(r-e),s=0;ht?new Array(i-t+1).join(" ")+this.src.slice(c,l):this.src.slice(c,l)}return u.join("")},n.prototype.Token=s,r.exports=n},{"../common/utils":4,"../token":51}],29:[function(e,r,t){"use strict";function n(e,r){var t=e.bMarks[r]+e.blkIndent,n=e.eMarks[r];return e.src.substr(t,n-t)}function s(e){var r,t=[],n=0,s=e.length,o=0,i=0,a=!1,c=0;for(r=e.charCodeAt(n);nt)return!1;if(p=r+1,e.sCount[p]=4)return!1;if((l=e.bMarks[p]+e.tShift[p])>=e.eMarks[p])return!1;if(124!==(a=e.src.charCodeAt(l++))&&45!==a&&58!==a)return!1;for(;l=4)return!1;if(h=s(c.replace(/^\||\|$/g,"")),(f=h.length)>m.length)return!1;if(i)return!0;for(d=e.push("table_open","table",1),d.map=g=[r,0],d=e.push("thead_open","thead",1),d.map=[r,r+1],d=e.push("tr_open","tr",1),d.map=[r,r+1],u=0;u=4);p++){for(h=s(c.replace(/^\||\|$/g,"")),d=e.push("tr_open","tr",1),u=0;u\s]/i.test(e)}function s(e){return/^<\/a\s*>/i.test(e)}var o=e("../common/utils").arrayReplaceAt;r.exports=function(e){var r,t,i,a,c,l,u,p,h,f,d,m,_,g,b,k,v,y=e.tokens;if(e.md.options.linkify)for(t=0,i=y.length;t=0;r--)if(l=a[r],"link_close"!==l.type){if("html_inline"===l.type&&(n(l.content)&&_>0&&_--,s(l.content)&&_++),!(_>0)&&"text"===l.type&&e.md.linkify.test(l.content)){for(h=l.content,v=e.md.linkify.match(h),u=[],m=l.level,d=0,p=0;pd&&(c=new e.Token("text","",0),c.content=h.slice(d,f),c.level=m,u.push(c)),c=new e.Token("link_open","a",1),c.attrs=[["href",b]],c.level=m++,c.markup="linkify",c.info="auto",u.push(c),c=new e.Token("text","",0),c.content=k,c.level=m,u.push(c),c=new e.Token("link_close","a",-1),c.level=--m,c.markup="linkify",c.info="auto",u.push(c),d=v[p].lastIndex);d=0;r--)t=e[r],"text"!==t.type||s||(t.content=t.content.replace(/\((c|tm|r|p)\)/gi,n)),"link_open"===t.type&&"auto"===t.info&&s--,"link_close"===t.type&&"auto"===t.info&&s++}function o(e){var r,t,n=0;for(r=e.length-1;r>=0;r--)t=e[r],"text"!==t.type||n||i.test(t.content)&&(t.content=t.content.replace(/\+-/g,"\xb1").replace(/\.{2,}/g,"\u2026").replace(/([?!])\u2026/g,"$1..").replace(/([?!]){4,}/g,"$1$1$1").replace(/,{2,}/g,",").replace(/(^|[^-])---([^-]|$)/gm,"$1\u2014$2").replace(/(^|\s)--(\s|$)/gm,"$1\u2013$2").replace(/(^|[^-\s])--([^-\s]|$)/gm,"$1\u2013$2")),"link_open"===t.type&&"auto"===t.info&&n--,"link_close"===t.type&&"auto"===t.info&&n++}var i=/\+-|\.\.|\?\?\?\?|!!!!|,,|--/,a=/\((c|tm|r|p)\)/i,c={c:"\xa9",r:"\xae",p:"\xa7",tm:"\u2122"};r.exports=function(e){var r;if(e.md.options.typographer)for(r=e.tokens.length-1;r>=0;r--)"inline"===e.tokens[r].type&&(a.test(e.tokens[r].content)&&s(e.tokens[r].children),i.test(e.tokens[r].content)&&o(e.tokens[r].children))}},{}],35:[function(e,r,t){"use strict";function n(e,r,t){return e.substr(0,r)+t+e.substr(r+1)}function s(e,r){var t,s,c,u,p,h,f,d,m,_,g,b,k,v,y,x,C,A,w,D,q;for(w=[],t=0;t=0&&!(w[C].level<=f);C--);if(w.length=C+1,"text"===s.type){c=s.content,p=0,h=c.length;e:for(;p=0)m=c.charCodeAt(u.index-1);else for(C=t-1;C>=0;C--)if("text"===e[C].type){m=e[C].content.charCodeAt(e[C].content.length-1);break}if(_=32,p=48&&m<=57&&(x=y=!1),y&&x&&(y=!1,x=b),y||x){if(x)for(C=w.length-1;C>=0&&(d=w[C],!(w[C].level=0;r--)"inline"===e.tokens[r].type&&c.test(e.tokens[r].content)&&s(e.tokens[r].children,e)}},{"../common/utils":4}],36:[function(e,r,t){"use strict";function n(e,r,t){this.src=e,this.env=t,this.tokens=[],this.inlineMode=!1,this.md=r}var s=e("../token");n.prototype.Token=s,r.exports=n},{"../token":51}],37:[function(e,r,t){"use strict";var n=/^<([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>/,s=/^<([a-zA-Z][a-zA-Z0-9+.\-]{1,31}):([^<>\x00-\x20]*)>/;r.exports=function(e,r){var t,o,i,a,c,l,u=e.pos;return 60===e.src.charCodeAt(u)&&(t=e.src.slice(u),!(t.indexOf(">")<0)&&(s.test(t)?(o=t.match(s),a=o[0].slice(1,-1),c=e.md.normalizeLink(a),!!e.md.validateLink(c)&&(r||(l=e.push("link_open","a",1),l.attrs=[["href",c]],l.markup="autolink",l.info="auto",l=e.push("text","",0),l.content=e.md.normalizeLinkText(a),l=e.push("link_close","a",-1),l.markup="autolink",l.info="auto"),e.pos+=o[0].length,!0)):!!n.test(t)&&(i=t.match(n),a=i[0].slice(1,-1),c=e.md.normalizeLink("mailto:"+a),!!e.md.validateLink(c)&&(r||(l=e.push("link_open","a",1),l.attrs=[["href",c]],l.markup="autolink",l.info="auto",l=e.push("text","",0),l.content=e.md.normalizeLinkText(a),l=e.push("link_close","a",-1),l.markup="autolink",l.info="auto"),e.pos+=i[0].length,!0))))}},{}],38:[function(e,r,t){"use strict";r.exports=function(e,r){var t,n,s,o,i,a,c=e.pos;if(96!==e.src.charCodeAt(c))return!1;for(t=c,c++,n=e.posMax;c=0;){if(s=o[t],s.open&&s.marker===n.marker&&s.end<0&&s.level===n.level){var a=(s.close||n.open)&&void 0!==s.length&&void 0!==n.length&&(s.length+n.length)%3==0;if(!a){n.jump=r-t,n.open=!1,s.end=r,s.jump=0;break}}t-=s.jump+1}}},{}],40:[function(e,r,t){"use strict";r.exports.tokenize=function(e,r){var t,n,s,o=e.pos,i=e.src.charCodeAt(o);if(r)return!1;if(95!==i&&42!==i)return!1;for(n=e.scanDelims(e.pos,42===i),t=0;t?@[]^_`{|}~-".split("").forEach(function(e){s[e.charCodeAt(0)]=1}),r.exports=function(e,r){var t,o=e.pos,i=e.posMax;if(92!==e.src.charCodeAt(o))return!1;if(++o=97&&r<=122}var s=e("../common/html_re").HTML_TAG_RE;r.exports=function(e,r){var t,o,i,a,c=e.pos;return!!e.md.options.html&&(i=e.posMax,!(60!==e.src.charCodeAt(c)||c+2>=i)&&(!(33!==(t=e.src.charCodeAt(c+1))&&63!==t&&47!==t&&!n(t))&&(!!(o=e.src.slice(c).match(s))&&(r||(a=e.push("html_inline","",0),a.content=e.src.slice(c,c+o[0].length)),e.pos+=o[0].length,!0))))}},{"../common/html_re":3}],44:[function(e,r,t){"use strict";var n=e("../common/utils").normalizeReference,s=e("../common/utils").isSpace;r.exports=function(e,r){var t,o,i,a,c,l,u,p,h,f,d,m,_,g="",b=e.pos,k=e.posMax;if(33!==e.src.charCodeAt(e.pos))return!1;if(91!==e.src.charCodeAt(e.pos+1))return!1;if(l=e.pos+2,(c=e.md.helpers.parseLinkLabel(e,e.pos+1,!1))<0)return!1;if((u=c+1)=k)return!1;for(_=u,h=e.md.helpers.parseLinkDestination(e.src,u,e.posMax),h.ok&&(g=e.md.normalizeLink(h.str),e.md.validateLink(g)?u=h.pos:g=""),_=u;u=k||41!==e.src.charCodeAt(u))return e.pos=b,!1;u++}else{if(void 0===e.env.references)return!1;if(u=0?a=e.src.slice(_,u++):u=c+1):u=c+1,a||(a=e.src.slice(l,c)),!(p=e.env.references[n(a)]))return e.pos=b,!1;g=p.href,f=p.title}return r||(i=e.src.slice(l,c),e.md.inline.parse(i,e.md,e.env,m=[]),d=e.push("image","img",0),d.attrs=t=[["src",g],["alt",""]],d.children=m,d.content=i,f&&t.push(["title",f])),e.pos=u,e.posMax=k,!0}},{"../common/utils":4}],45:[function(e,r,t){"use strict";var n=e("../common/utils").normalizeReference,s=e("../common/utils").isSpace;r.exports=function(e,r){var t,o,i,a,c,l,u,p,h,f,d="",m=e.pos,_=e.posMax,g=e.pos,b=!0;if(91!==e.src.charCodeAt(e.pos))return!1;if(c=e.pos+1,(a=e.md.helpers.parseLinkLabel(e,e.pos,!0))<0)return!1;if((l=a+1)<_&&40===e.src.charCodeAt(l)){for(b=!1,l++;l<_&&(o=e.src.charCodeAt(l),s(o)||10===o);l++);if(l>=_)return!1;for(g=l,u=e.md.helpers.parseLinkDestination(e.src,l,e.posMax),u.ok&&(d=e.md.normalizeLink(u.str),e.md.validateLink(d)?l=u.pos:d=""),g=l;l<_&&(o=e.src.charCodeAt(l),s(o)||10===o);l++);if(u=e.md.helpers.parseLinkTitle(e.src,l,e.posMax),l<_&&g!==l&&u.ok)for(h=u.str,l=u.pos;l<_&&(o=e.src.charCodeAt(l),s(o)||10===o);l++);else h="";(l>=_||41!==e.src.charCodeAt(l))&&(b=!0),l++}if(b){if(void 0===e.env.references)return!1;if(l<_&&91===e.src.charCodeAt(l)?(g=l+1,l=e.md.helpers.parseLinkLabel(e,l),l>=0?i=e.src.slice(g,l++):l=a+1):l=a+1,i||(i=e.src.slice(c,a)),!(p=e.env.references[n(i)]))return e.pos=m,!1;d=p.href,h=p.title}return r||(e.pos=c,e.posMax=a,f=e.push("link_open","a",1),f.attrs=t=[["href",d]],h&&t.push(["title",h]),e.md.inline.tokenize(e),f=e.push("link_close","a",-1)),e.pos=l,e.posMax=_,!0}},{"../common/utils":4}],46:[function(e,r,t){"use strict";var n=e("../common/utils").isSpace;r.exports=function(e,r){var t,s,o=e.pos;if(10!==e.src.charCodeAt(o))return!1;for(t=e.pending.length-1,s=e.posMax,r||(t>=0&&32===e.pending.charCodeAt(t)?t>=1&&32===e.pending.charCodeAt(t-1)?(e.pending=e.pending.replace(/ +$/,""),e.push("hardbreak","br",0)):(e.pending=e.pending.slice(0,-1),e.push("softbreak","br",0)):e.push("softbreak","br",0)),o++;o0&&this.level++,this.pendingLevel=this.level,this.tokens.push(n),n},n.prototype.scanDelims=function(e,r){var t,n,s,c,l,u,p,h,f,d=e,m=!0,_=!0,g=this.posMax,b=this.src.charCodeAt(e);for(t=e>0?this.src.charCodeAt(e-1):32;d=0&&(t=this.attrs[r][1]),t},n.prototype.attrJoin=function(e,r){var t=this.attrIndex(e);t<0?this.attrPush([e,r]):this.attrs[t][1]=this.attrs[t][1]+" "+r},r.exports=n},{}],52:[function(e,r,t){r.exports={Aacute:"\xc1",aacute:"\xe1",Abreve:"\u0102",abreve:"\u0103",ac:"\u223e",acd:"\u223f",acE:"\u223e\u0333",Acirc:"\xc2",acirc:"\xe2",acute:"\xb4",Acy:"\u0410",acy:"\u0430",AElig:"\xc6",aelig:"\xe6",af:"\u2061",Afr:"\ud835\udd04",afr:"\ud835\udd1e",Agrave:"\xc0",agrave:"\xe0",alefsym:"\u2135",aleph:"\u2135",Alpha:"\u0391",alpha:"\u03b1",Amacr:"\u0100",amacr:"\u0101",amalg:"\u2a3f",amp:"&",AMP:"&",andand:"\u2a55",And:"\u2a53",and:"\u2227",andd:"\u2a5c",andslope:"\u2a58",andv:"\u2a5a",ang:"\u2220",ange:"\u29a4",angle:"\u2220",angmsdaa:"\u29a8",angmsdab:"\u29a9",angmsdac:"\u29aa",angmsdad:"\u29ab",angmsdae:"\u29ac",angmsdaf:"\u29ad",angmsdag:"\u29ae",angmsdah:"\u29af",angmsd:"\u2221",angrt:"\u221f",angrtvb:"\u22be",angrtvbd:"\u299d",angsph:"\u2222",angst:"\xc5",angzarr:"\u237c",Aogon:"\u0104",aogon:"\u0105",Aopf:"\ud835\udd38",aopf:"\ud835\udd52",apacir:"\u2a6f",ap:"\u2248",apE:"\u2a70",ape:"\u224a",apid:"\u224b",apos:"'",ApplyFunction:"\u2061",approx:"\u2248",approxeq:"\u224a",Aring:"\xc5",aring:"\xe5",Ascr:"\ud835\udc9c",ascr:"\ud835\udcb6",Assign:"\u2254",ast:"*",asymp:"\u2248",asympeq:"\u224d",Atilde:"\xc3",atilde:"\xe3",Auml:"\xc4",auml:"\xe4",awconint:"\u2233",awint:"\u2a11",backcong:"\u224c",backepsilon:"\u03f6",backprime:"\u2035",backsim:"\u223d",backsimeq:"\u22cd",Backslash:"\u2216",Barv:"\u2ae7",barvee:"\u22bd",barwed:"\u2305",Barwed:"\u2306",barwedge:"\u2305",bbrk:"\u23b5",bbrktbrk:"\u23b6",bcong:"\u224c",Bcy:"\u0411",bcy:"\u0431",bdquo:"\u201e",becaus:"\u2235",because:"\u2235",Because:"\u2235",bemptyv:"\u29b0",bepsi:"\u03f6",bernou:"\u212c",Bernoullis:"\u212c",Beta:"\u0392",beta:"\u03b2",beth:"\u2136",between:"\u226c",Bfr:"\ud835\udd05",bfr:"\ud835\udd1f",bigcap:"\u22c2",bigcirc:"\u25ef",bigcup:"\u22c3",bigodot:"\u2a00",bigoplus:"\u2a01",bigotimes:"\u2a02",bigsqcup:"\u2a06",bigstar:"\u2605",bigtriangledown:"\u25bd",bigtriangleup:"\u25b3",biguplus:"\u2a04",bigvee:"\u22c1",bigwedge:"\u22c0",bkarow:"\u290d",blacklozenge:"\u29eb",blacksquare:"\u25aa",blacktriangle:"\u25b4",blacktriangledown:"\u25be",blacktriangleleft:"\u25c2",blacktriangleright:"\u25b8",blank:"\u2423",blk12:"\u2592",blk14:"\u2591",blk34:"\u2593",block:"\u2588",bne:"=\u20e5",bnequiv:"\u2261\u20e5",bNot:"\u2aed",bnot:"\u2310",Bopf:"\ud835\udd39",bopf:"\ud835\udd53",bot:"\u22a5",bottom:"\u22a5",bowtie:"\u22c8",boxbox:"\u29c9",boxdl:"\u2510",boxdL:"\u2555",boxDl:"\u2556",boxDL:"\u2557",boxdr:"\u250c",boxdR:"\u2552",boxDr:"\u2553",boxDR:"\u2554",boxh:"\u2500",boxH:"\u2550",boxhd:"\u252c",boxHd:"\u2564",boxhD:"\u2565",boxHD:"\u2566",boxhu:"\u2534",boxHu:"\u2567",boxhU:"\u2568",boxHU:"\u2569",boxminus:"\u229f",boxplus:"\u229e",boxtimes:"\u22a0",boxul:"\u2518",boxuL:"\u255b",boxUl:"\u255c",boxUL:"\u255d",boxur:"\u2514",boxuR:"\u2558",boxUr:"\u2559",boxUR:"\u255a",boxv:"\u2502",boxV:"\u2551",boxvh:"\u253c",boxvH:"\u256a",boxVh:"\u256b",boxVH:"\u256c",boxvl:"\u2524",boxvL:"\u2561",boxVl:"\u2562",boxVL:"\u2563",boxvr:"\u251c",boxvR:"\u255e",boxVr:"\u255f",boxVR:"\u2560",bprime:"\u2035",breve:"\u02d8",Breve:"\u02d8",brvbar:"\xa6",bscr:"\ud835\udcb7",Bscr:"\u212c",bsemi:"\u204f",bsim:"\u223d",bsime:"\u22cd",bsolb:"\u29c5",bsol:"\\",bsolhsub:"\u27c8",bull:"\u2022",bullet:"\u2022",bump:"\u224e",bumpE:"\u2aae",bumpe:"\u224f",Bumpeq:"\u224e",bumpeq:"\u224f",Cacute:"\u0106",cacute:"\u0107",capand:"\u2a44",capbrcup:"\u2a49",capcap:"\u2a4b",cap:"\u2229",Cap:"\u22d2",capcup:"\u2a47",capdot:"\u2a40",CapitalDifferentialD:"\u2145",caps:"\u2229\ufe00",caret:"\u2041",caron:"\u02c7",Cayleys:"\u212d",ccaps:"\u2a4d",Ccaron:"\u010c",ccaron:"\u010d",Ccedil:"\xc7",ccedil:"\xe7",Ccirc:"\u0108",ccirc:"\u0109",Cconint:"\u2230",ccups:"\u2a4c",ccupssm:"\u2a50",Cdot:"\u010a",cdot:"\u010b",cedil:"\xb8",Cedilla:"\xb8",cemptyv:"\u29b2",cent:"\xa2",centerdot:"\xb7",CenterDot:"\xb7",cfr:"\ud835\udd20",Cfr:"\u212d",CHcy:"\u0427",chcy:"\u0447",check:"\u2713",checkmark:"\u2713",Chi:"\u03a7",chi:"\u03c7",circ:"\u02c6",circeq:"\u2257",circlearrowleft:"\u21ba",circlearrowright:"\u21bb",circledast:"\u229b",circledcirc:"\u229a",circleddash:"\u229d",CircleDot:"\u2299",circledR:"\xae",circledS:"\u24c8",CircleMinus:"\u2296",CirclePlus:"\u2295",CircleTimes:"\u2297",cir:"\u25cb",cirE:"\u29c3",cire:"\u2257",cirfnint:"\u2a10",cirmid:"\u2aef",cirscir:"\u29c2",ClockwiseContourIntegral:"\u2232",CloseCurlyDoubleQuote:"\u201d",CloseCurlyQuote:"\u2019",clubs:"\u2663",clubsuit:"\u2663",colon:":",Colon:"\u2237",Colone:"\u2a74",colone:"\u2254",coloneq:"\u2254",comma:",",commat:"@",comp:"\u2201",compfn:"\u2218",complement:"\u2201",complexes:"\u2102",cong:"\u2245",congdot:"\u2a6d",Congruent:"\u2261",conint:"\u222e",Conint:"\u222f",ContourIntegral:"\u222e",copf:"\ud835\udd54",Copf:"\u2102",coprod:"\u2210",Coproduct:"\u2210",copy:"\xa9",COPY:"\xa9",copysr:"\u2117",CounterClockwiseContourIntegral:"\u2233",crarr:"\u21b5",cross:"\u2717",Cross:"\u2a2f",Cscr:"\ud835\udc9e",cscr:"\ud835\udcb8",csub:"\u2acf",csube:"\u2ad1",csup:"\u2ad0",csupe:"\u2ad2",ctdot:"\u22ef",cudarrl:"\u2938",cudarrr:"\u2935",cuepr:"\u22de",cuesc:"\u22df",cularr:"\u21b6",cularrp:"\u293d",cupbrcap:"\u2a48",cupcap:"\u2a46",CupCap:"\u224d",cup:"\u222a",Cup:"\u22d3",cupcup:"\u2a4a",cupdot:"\u228d",cupor:"\u2a45",cups:"\u222a\ufe00",curarr:"\u21b7",curarrm:"\u293c",curlyeqprec:"\u22de",curlyeqsucc:"\u22df",curlyvee:"\u22ce",curlywedge:"\u22cf",curren:"\xa4",curvearrowleft:"\u21b6",curvearrowright:"\u21b7",cuvee:"\u22ce",cuwed:"\u22cf",cwconint:"\u2232",cwint:"\u2231",cylcty:"\u232d",dagger:"\u2020",Dagger:"\u2021",daleth:"\u2138",darr:"\u2193",Darr:"\u21a1",dArr:"\u21d3",dash:"\u2010",Dashv:"\u2ae4",dashv:"\u22a3",dbkarow:"\u290f",dblac:"\u02dd",Dcaron:"\u010e",dcaron:"\u010f",Dcy:"\u0414",dcy:"\u0434",ddagger:"\u2021",ddarr:"\u21ca",DD:"\u2145",dd:"\u2146",DDotrahd:"\u2911",ddotseq:"\u2a77",deg:"\xb0",Del:"\u2207",Delta:"\u0394",delta:"\u03b4",demptyv:"\u29b1",dfisht:"\u297f",Dfr:"\ud835\udd07",dfr:"\ud835\udd21",dHar:"\u2965",dharl:"\u21c3",dharr:"\u21c2",DiacriticalAcute:"\xb4",DiacriticalDot:"\u02d9",DiacriticalDoubleAcute:"\u02dd",DiacriticalGrave:"`",DiacriticalTilde:"\u02dc",diam:"\u22c4",diamond:"\u22c4",Diamond:"\u22c4",diamondsuit:"\u2666",diams:"\u2666",die:"\xa8",DifferentialD:"\u2146",digamma:"\u03dd",disin:"\u22f2",div:"\xf7",divide:"\xf7",divideontimes:"\u22c7",divonx:"\u22c7",DJcy:"\u0402",djcy:"\u0452",dlcorn:"\u231e",dlcrop:"\u230d",dollar:"$",Dopf:"\ud835\udd3b",dopf:"\ud835\udd55",Dot:"\xa8",dot:"\u02d9",DotDot:"\u20dc",doteq:"\u2250",doteqdot:"\u2251",DotEqual:"\u2250",dotminus:"\u2238",dotplus:"\u2214",dotsquare:"\u22a1",doublebarwedge:"\u2306",DoubleContourIntegral:"\u222f",DoubleDot:"\xa8",DoubleDownArrow:"\u21d3",DoubleLeftArrow:"\u21d0",DoubleLeftRightArrow:"\u21d4",DoubleLeftTee:"\u2ae4",DoubleLongLeftArrow:"\u27f8",DoubleLongLeftRightArrow:"\u27fa",DoubleLongRightArrow:"\u27f9",DoubleRightArrow:"\u21d2",DoubleRightTee:"\u22a8",DoubleUpArrow:"\u21d1",DoubleUpDownArrow:"\u21d5",DoubleVerticalBar:"\u2225",DownArrowBar:"\u2913",downarrow:"\u2193",DownArrow:"\u2193",Downarrow:"\u21d3",DownArrowUpArrow:"\u21f5",DownBreve:"\u0311",downdownarrows:"\u21ca",downharpoonleft:"\u21c3",downharpoonright:"\u21c2",DownLeftRightVector:"\u2950",DownLeftTeeVector:"\u295e",DownLeftVectorBar:"\u2956",DownLeftVector:"\u21bd",DownRightTeeVector:"\u295f",DownRightVectorBar:"\u2957",DownRightVector:"\u21c1",DownTeeArrow:"\u21a7",DownTee:"\u22a4",drbkarow:"\u2910",drcorn:"\u231f",drcrop:"\u230c",Dscr:"\ud835\udc9f",dscr:"\ud835\udcb9",DScy:"\u0405",dscy:"\u0455",dsol:"\u29f6",Dstrok:"\u0110",dstrok:"\u0111",dtdot:"\u22f1",dtri:"\u25bf",dtrif:"\u25be",duarr:"\u21f5",duhar:"\u296f",dwangle:"\u29a6",DZcy:"\u040f",dzcy:"\u045f",dzigrarr:"\u27ff",Eacute:"\xc9",eacute:"\xe9",easter:"\u2a6e",Ecaron:"\u011a",ecaron:"\u011b",Ecirc:"\xca",ecirc:"\xea",ecir:"\u2256",ecolon:"\u2255",Ecy:"\u042d",ecy:"\u044d",eDDot:"\u2a77",Edot:"\u0116",edot:"\u0117",eDot:"\u2251",ee:"\u2147",efDot:"\u2252",Efr:"\ud835\udd08",efr:"\ud835\udd22",eg:"\u2a9a",Egrave:"\xc8",egrave:"\xe8",egs:"\u2a96",egsdot:"\u2a98",el:"\u2a99",Element:"\u2208",elinters:"\u23e7",ell:"\u2113",els:"\u2a95",elsdot:"\u2a97",Emacr:"\u0112",emacr:"\u0113",empty:"\u2205",emptyset:"\u2205",EmptySmallSquare:"\u25fb",emptyv:"\u2205",EmptyVerySmallSquare:"\u25ab",emsp13:"\u2004",emsp14:"\u2005",emsp:"\u2003",ENG:"\u014a",eng:"\u014b",ensp:"\u2002",Eogon:"\u0118",eogon:"\u0119",Eopf:"\ud835\udd3c",eopf:"\ud835\udd56",epar:"\u22d5",eparsl:"\u29e3",eplus:"\u2a71",epsi:"\u03b5",Epsilon:"\u0395",epsilon:"\u03b5",epsiv:"\u03f5",eqcirc:"\u2256",eqcolon:"\u2255",eqsim:"\u2242",eqslantgtr:"\u2a96",eqslantless:"\u2a95",Equal:"\u2a75",equals:"=",EqualTilde:"\u2242",equest:"\u225f",Equilibrium:"\u21cc",equiv:"\u2261",equivDD:"\u2a78",eqvparsl:"\u29e5",erarr:"\u2971",erDot:"\u2253",escr:"\u212f",Escr:"\u2130",esdot:"\u2250",Esim:"\u2a73",esim:"\u2242",Eta:"\u0397",eta:"\u03b7",ETH:"\xd0",eth:"\xf0",Euml:"\xcb",euml:"\xeb",euro:"\u20ac",excl:"!",exist:"\u2203",Exists:"\u2203",expectation:"\u2130",exponentiale:"\u2147",ExponentialE:"\u2147",fallingdotseq:"\u2252",Fcy:"\u0424",fcy:"\u0444",female:"\u2640",ffilig:"\ufb03",fflig:"\ufb00",ffllig:"\ufb04",Ffr:"\ud835\udd09",ffr:"\ud835\udd23",filig:"\ufb01",FilledSmallSquare:"\u25fc",FilledVerySmallSquare:"\u25aa",fjlig:"fj",flat:"\u266d",fllig:"\ufb02",fltns:"\u25b1",fnof:"\u0192",Fopf:"\ud835\udd3d",fopf:"\ud835\udd57",forall:"\u2200",ForAll:"\u2200",fork:"\u22d4",forkv:"\u2ad9",Fouriertrf:"\u2131",fpartint:"\u2a0d",frac12:"\xbd",frac13:"\u2153",frac14:"\xbc",frac15:"\u2155",frac16:"\u2159",frac18:"\u215b",frac23:"\u2154",frac25:"\u2156",frac34:"\xbe",frac35:"\u2157",frac38:"\u215c",frac45:"\u2158",frac56:"\u215a",frac58:"\u215d",frac78:"\u215e",frasl:"\u2044",frown:"\u2322",fscr:"\ud835\udcbb",Fscr:"\u2131",gacute:"\u01f5",Gamma:"\u0393",gamma:"\u03b3",Gammad:"\u03dc",gammad:"\u03dd",gap:"\u2a86",Gbreve:"\u011e",gbreve:"\u011f",Gcedil:"\u0122",Gcirc:"\u011c",gcirc:"\u011d",Gcy:"\u0413",gcy:"\u0433",Gdot:"\u0120",gdot:"\u0121",ge:"\u2265",gE:"\u2267",gEl:"\u2a8c",gel:"\u22db",geq:"\u2265",geqq:"\u2267",geqslant:"\u2a7e",gescc:"\u2aa9",ges:"\u2a7e",gesdot:"\u2a80",gesdoto:"\u2a82",gesdotol:"\u2a84",gesl:"\u22db\ufe00",gesles:"\u2a94",Gfr:"\ud835\udd0a",gfr:"\ud835\udd24",gg:"\u226b",Gg:"\u22d9",ggg:"\u22d9",gimel:"\u2137",GJcy:"\u0403",gjcy:"\u0453",gla:"\u2aa5",gl:"\u2277",glE:"\u2a92",glj:"\u2aa4",gnap:"\u2a8a",gnapprox:"\u2a8a",gne:"\u2a88",gnE:"\u2269",gneq:"\u2a88",gneqq:"\u2269",gnsim:"\u22e7",Gopf:"\ud835\udd3e",gopf:"\ud835\udd58",grave:"`",GreaterEqual:"\u2265",GreaterEqualLess:"\u22db",GreaterFullEqual:"\u2267",GreaterGreater:"\u2aa2",GreaterLess:"\u2277",GreaterSlantEqual:"\u2a7e",GreaterTilde:"\u2273",Gscr:"\ud835\udca2",gscr:"\u210a",gsim:"\u2273",gsime:"\u2a8e",gsiml:"\u2a90",gtcc:"\u2aa7",gtcir:"\u2a7a",gt:">",GT:">",Gt:"\u226b",gtdot:"\u22d7",gtlPar:"\u2995",gtquest:"\u2a7c",gtrapprox:"\u2a86",gtrarr:"\u2978",gtrdot:"\u22d7",gtreqless:"\u22db",gtreqqless:"\u2a8c",gtrless:"\u2277",gtrsim:"\u2273",gvertneqq:"\u2269\ufe00",gvnE:"\u2269\ufe00",Hacek:"\u02c7",hairsp:"\u200a",half:"\xbd",hamilt:"\u210b",HARDcy:"\u042a",hardcy:"\u044a",harrcir:"\u2948",harr:"\u2194",hArr:"\u21d4",harrw:"\u21ad",Hat:"^",hbar:"\u210f",Hcirc:"\u0124",hcirc:"\u0125",hearts:"\u2665",heartsuit:"\u2665",hellip:"\u2026",hercon:"\u22b9",hfr:"\ud835\udd25",Hfr:"\u210c",HilbertSpace:"\u210b",hksearow:"\u2925",hkswarow:"\u2926",hoarr:"\u21ff",homtht:"\u223b",hookleftarrow:"\u21a9",hookrightarrow:"\u21aa",hopf:"\ud835\udd59",Hopf:"\u210d",horbar:"\u2015",HorizontalLine:"\u2500",hscr:"\ud835\udcbd",Hscr:"\u210b",hslash:"\u210f",Hstrok:"\u0126",hstrok:"\u0127",HumpDownHump:"\u224e",HumpEqual:"\u224f",hybull:"\u2043",hyphen:"\u2010",Iacute:"\xcd",iacute:"\xed",ic:"\u2063",Icirc:"\xce",icirc:"\xee",Icy:"\u0418",icy:"\u0438",Idot:"\u0130",IEcy:"\u0415",iecy:"\u0435",iexcl:"\xa1",iff:"\u21d4",ifr:"\ud835\udd26",Ifr:"\u2111",Igrave:"\xcc",igrave:"\xec",ii:"\u2148",iiiint:"\u2a0c",iiint:"\u222d",iinfin:"\u29dc",iiota:"\u2129",IJlig:"\u0132",ijlig:"\u0133",Imacr:"\u012a",imacr:"\u012b",image:"\u2111",ImaginaryI:"\u2148",imagline:"\u2110",imagpart:"\u2111",imath:"\u0131",Im:"\u2111",imof:"\u22b7",imped:"\u01b5",Implies:"\u21d2",incare:"\u2105",in:"\u2208",infin:"\u221e",infintie:"\u29dd",inodot:"\u0131",intcal:"\u22ba",int:"\u222b",Int:"\u222c",integers:"\u2124",Integral:"\u222b",intercal:"\u22ba",Intersection:"\u22c2",intlarhk:"\u2a17",intprod:"\u2a3c",InvisibleComma:"\u2063",InvisibleTimes:"\u2062",IOcy:"\u0401",iocy:"\u0451",Iogon:"\u012e",iogon:"\u012f",Iopf:"\ud835\udd40",iopf:"\ud835\udd5a",Iota:"\u0399",iota:"\u03b9",iprod:"\u2a3c",iquest:"\xbf",iscr:"\ud835\udcbe",Iscr:"\u2110",isin:"\u2208",isindot:"\u22f5",isinE:"\u22f9",isins:"\u22f4",isinsv:"\u22f3",isinv:"\u2208",it:"\u2062",Itilde:"\u0128",itilde:"\u0129",Iukcy:"\u0406",iukcy:"\u0456",Iuml:"\xcf",iuml:"\xef",Jcirc:"\u0134",jcirc:"\u0135",Jcy:"\u0419",jcy:"\u0439",Jfr:"\ud835\udd0d",jfr:"\ud835\udd27",jmath:"\u0237",Jopf:"\ud835\udd41", -jopf:"\ud835\udd5b",Jscr:"\ud835\udca5",jscr:"\ud835\udcbf",Jsercy:"\u0408",jsercy:"\u0458",Jukcy:"\u0404",jukcy:"\u0454",Kappa:"\u039a",kappa:"\u03ba",kappav:"\u03f0",Kcedil:"\u0136",kcedil:"\u0137",Kcy:"\u041a",kcy:"\u043a",Kfr:"\ud835\udd0e",kfr:"\ud835\udd28",kgreen:"\u0138",KHcy:"\u0425",khcy:"\u0445",KJcy:"\u040c",kjcy:"\u045c",Kopf:"\ud835\udd42",kopf:"\ud835\udd5c",Kscr:"\ud835\udca6",kscr:"\ud835\udcc0",lAarr:"\u21da",Lacute:"\u0139",lacute:"\u013a",laemptyv:"\u29b4",lagran:"\u2112",Lambda:"\u039b",lambda:"\u03bb",lang:"\u27e8",Lang:"\u27ea",langd:"\u2991",langle:"\u27e8",lap:"\u2a85",Laplacetrf:"\u2112",laquo:"\xab",larrb:"\u21e4",larrbfs:"\u291f",larr:"\u2190",Larr:"\u219e",lArr:"\u21d0",larrfs:"\u291d",larrhk:"\u21a9",larrlp:"\u21ab",larrpl:"\u2939",larrsim:"\u2973",larrtl:"\u21a2",latail:"\u2919",lAtail:"\u291b",lat:"\u2aab",late:"\u2aad",lates:"\u2aad\ufe00",lbarr:"\u290c",lBarr:"\u290e",lbbrk:"\u2772",lbrace:"{",lbrack:"[",lbrke:"\u298b",lbrksld:"\u298f",lbrkslu:"\u298d",Lcaron:"\u013d",lcaron:"\u013e",Lcedil:"\u013b",lcedil:"\u013c",lceil:"\u2308",lcub:"{",Lcy:"\u041b",lcy:"\u043b",ldca:"\u2936",ldquo:"\u201c",ldquor:"\u201e",ldrdhar:"\u2967",ldrushar:"\u294b",ldsh:"\u21b2",le:"\u2264",lE:"\u2266",LeftAngleBracket:"\u27e8",LeftArrowBar:"\u21e4",leftarrow:"\u2190",LeftArrow:"\u2190",Leftarrow:"\u21d0",LeftArrowRightArrow:"\u21c6",leftarrowtail:"\u21a2",LeftCeiling:"\u2308",LeftDoubleBracket:"\u27e6",LeftDownTeeVector:"\u2961",LeftDownVectorBar:"\u2959",LeftDownVector:"\u21c3",LeftFloor:"\u230a",leftharpoondown:"\u21bd",leftharpoonup:"\u21bc",leftleftarrows:"\u21c7",leftrightarrow:"\u2194",LeftRightArrow:"\u2194",Leftrightarrow:"\u21d4",leftrightarrows:"\u21c6",leftrightharpoons:"\u21cb",leftrightsquigarrow:"\u21ad",LeftRightVector:"\u294e",LeftTeeArrow:"\u21a4",LeftTee:"\u22a3",LeftTeeVector:"\u295a",leftthreetimes:"\u22cb",LeftTriangleBar:"\u29cf",LeftTriangle:"\u22b2",LeftTriangleEqual:"\u22b4",LeftUpDownVector:"\u2951",LeftUpTeeVector:"\u2960",LeftUpVectorBar:"\u2958",LeftUpVector:"\u21bf",LeftVectorBar:"\u2952",LeftVector:"\u21bc",lEg:"\u2a8b",leg:"\u22da",leq:"\u2264",leqq:"\u2266",leqslant:"\u2a7d",lescc:"\u2aa8",les:"\u2a7d",lesdot:"\u2a7f",lesdoto:"\u2a81",lesdotor:"\u2a83",lesg:"\u22da\ufe00",lesges:"\u2a93",lessapprox:"\u2a85",lessdot:"\u22d6",lesseqgtr:"\u22da",lesseqqgtr:"\u2a8b",LessEqualGreater:"\u22da",LessFullEqual:"\u2266",LessGreater:"\u2276",lessgtr:"\u2276",LessLess:"\u2aa1",lesssim:"\u2272",LessSlantEqual:"\u2a7d",LessTilde:"\u2272",lfisht:"\u297c",lfloor:"\u230a",Lfr:"\ud835\udd0f",lfr:"\ud835\udd29",lg:"\u2276",lgE:"\u2a91",lHar:"\u2962",lhard:"\u21bd",lharu:"\u21bc",lharul:"\u296a",lhblk:"\u2584",LJcy:"\u0409",ljcy:"\u0459",llarr:"\u21c7",ll:"\u226a",Ll:"\u22d8",llcorner:"\u231e",Lleftarrow:"\u21da",llhard:"\u296b",lltri:"\u25fa",Lmidot:"\u013f",lmidot:"\u0140",lmoustache:"\u23b0",lmoust:"\u23b0",lnap:"\u2a89",lnapprox:"\u2a89",lne:"\u2a87",lnE:"\u2268",lneq:"\u2a87",lneqq:"\u2268",lnsim:"\u22e6",loang:"\u27ec",loarr:"\u21fd",lobrk:"\u27e6",longleftarrow:"\u27f5",LongLeftArrow:"\u27f5",Longleftarrow:"\u27f8",longleftrightarrow:"\u27f7",LongLeftRightArrow:"\u27f7",Longleftrightarrow:"\u27fa",longmapsto:"\u27fc",longrightarrow:"\u27f6",LongRightArrow:"\u27f6",Longrightarrow:"\u27f9",looparrowleft:"\u21ab",looparrowright:"\u21ac",lopar:"\u2985",Lopf:"\ud835\udd43",lopf:"\ud835\udd5d",loplus:"\u2a2d",lotimes:"\u2a34",lowast:"\u2217",lowbar:"_",LowerLeftArrow:"\u2199",LowerRightArrow:"\u2198",loz:"\u25ca",lozenge:"\u25ca",lozf:"\u29eb",lpar:"(",lparlt:"\u2993",lrarr:"\u21c6",lrcorner:"\u231f",lrhar:"\u21cb",lrhard:"\u296d",lrm:"\u200e",lrtri:"\u22bf",lsaquo:"\u2039",lscr:"\ud835\udcc1",Lscr:"\u2112",lsh:"\u21b0",Lsh:"\u21b0",lsim:"\u2272",lsime:"\u2a8d",lsimg:"\u2a8f",lsqb:"[",lsquo:"\u2018",lsquor:"\u201a",Lstrok:"\u0141",lstrok:"\u0142",ltcc:"\u2aa6",ltcir:"\u2a79",lt:"<",LT:"<",Lt:"\u226a",ltdot:"\u22d6",lthree:"\u22cb",ltimes:"\u22c9",ltlarr:"\u2976",ltquest:"\u2a7b",ltri:"\u25c3",ltrie:"\u22b4",ltrif:"\u25c2",ltrPar:"\u2996",lurdshar:"\u294a",luruhar:"\u2966",lvertneqq:"\u2268\ufe00",lvnE:"\u2268\ufe00",macr:"\xaf",male:"\u2642",malt:"\u2720",maltese:"\u2720",Map:"\u2905",map:"\u21a6",mapsto:"\u21a6",mapstodown:"\u21a7",mapstoleft:"\u21a4",mapstoup:"\u21a5",marker:"\u25ae",mcomma:"\u2a29",Mcy:"\u041c",mcy:"\u043c",mdash:"\u2014",mDDot:"\u223a",measuredangle:"\u2221",MediumSpace:"\u205f",Mellintrf:"\u2133",Mfr:"\ud835\udd10",mfr:"\ud835\udd2a",mho:"\u2127",micro:"\xb5",midast:"*",midcir:"\u2af0",mid:"\u2223",middot:"\xb7",minusb:"\u229f",minus:"\u2212",minusd:"\u2238",minusdu:"\u2a2a",MinusPlus:"\u2213",mlcp:"\u2adb",mldr:"\u2026",mnplus:"\u2213",models:"\u22a7",Mopf:"\ud835\udd44",mopf:"\ud835\udd5e",mp:"\u2213",mscr:"\ud835\udcc2",Mscr:"\u2133",mstpos:"\u223e",Mu:"\u039c",mu:"\u03bc",multimap:"\u22b8",mumap:"\u22b8",nabla:"\u2207",Nacute:"\u0143",nacute:"\u0144",nang:"\u2220\u20d2",nap:"\u2249",napE:"\u2a70\u0338",napid:"\u224b\u0338",napos:"\u0149",napprox:"\u2249",natural:"\u266e",naturals:"\u2115",natur:"\u266e",nbsp:"\xa0",nbump:"\u224e\u0338",nbumpe:"\u224f\u0338",ncap:"\u2a43",Ncaron:"\u0147",ncaron:"\u0148",Ncedil:"\u0145",ncedil:"\u0146",ncong:"\u2247",ncongdot:"\u2a6d\u0338",ncup:"\u2a42",Ncy:"\u041d",ncy:"\u043d",ndash:"\u2013",nearhk:"\u2924",nearr:"\u2197",neArr:"\u21d7",nearrow:"\u2197",ne:"\u2260",nedot:"\u2250\u0338",NegativeMediumSpace:"\u200b",NegativeThickSpace:"\u200b",NegativeThinSpace:"\u200b",NegativeVeryThinSpace:"\u200b",nequiv:"\u2262",nesear:"\u2928",nesim:"\u2242\u0338",NestedGreaterGreater:"\u226b",NestedLessLess:"\u226a",NewLine:"\n",nexist:"\u2204",nexists:"\u2204",Nfr:"\ud835\udd11",nfr:"\ud835\udd2b",ngE:"\u2267\u0338",nge:"\u2271",ngeq:"\u2271",ngeqq:"\u2267\u0338",ngeqslant:"\u2a7e\u0338",nges:"\u2a7e\u0338",nGg:"\u22d9\u0338",ngsim:"\u2275",nGt:"\u226b\u20d2",ngt:"\u226f",ngtr:"\u226f",nGtv:"\u226b\u0338",nharr:"\u21ae",nhArr:"\u21ce",nhpar:"\u2af2",ni:"\u220b",nis:"\u22fc",nisd:"\u22fa",niv:"\u220b",NJcy:"\u040a",njcy:"\u045a",nlarr:"\u219a",nlArr:"\u21cd",nldr:"\u2025",nlE:"\u2266\u0338",nle:"\u2270",nleftarrow:"\u219a",nLeftarrow:"\u21cd",nleftrightarrow:"\u21ae",nLeftrightarrow:"\u21ce",nleq:"\u2270",nleqq:"\u2266\u0338",nleqslant:"\u2a7d\u0338",nles:"\u2a7d\u0338",nless:"\u226e",nLl:"\u22d8\u0338",nlsim:"\u2274",nLt:"\u226a\u20d2",nlt:"\u226e",nltri:"\u22ea",nltrie:"\u22ec",nLtv:"\u226a\u0338",nmid:"\u2224",NoBreak:"\u2060",NonBreakingSpace:"\xa0",nopf:"\ud835\udd5f",Nopf:"\u2115",Not:"\u2aec",not:"\xac",NotCongruent:"\u2262",NotCupCap:"\u226d",NotDoubleVerticalBar:"\u2226",NotElement:"\u2209",NotEqual:"\u2260",NotEqualTilde:"\u2242\u0338",NotExists:"\u2204",NotGreater:"\u226f",NotGreaterEqual:"\u2271",NotGreaterFullEqual:"\u2267\u0338",NotGreaterGreater:"\u226b\u0338",NotGreaterLess:"\u2279",NotGreaterSlantEqual:"\u2a7e\u0338",NotGreaterTilde:"\u2275",NotHumpDownHump:"\u224e\u0338",NotHumpEqual:"\u224f\u0338",notin:"\u2209",notindot:"\u22f5\u0338",notinE:"\u22f9\u0338",notinva:"\u2209",notinvb:"\u22f7",notinvc:"\u22f6",NotLeftTriangleBar:"\u29cf\u0338",NotLeftTriangle:"\u22ea",NotLeftTriangleEqual:"\u22ec",NotLess:"\u226e",NotLessEqual:"\u2270",NotLessGreater:"\u2278",NotLessLess:"\u226a\u0338",NotLessSlantEqual:"\u2a7d\u0338",NotLessTilde:"\u2274",NotNestedGreaterGreater:"\u2aa2\u0338",NotNestedLessLess:"\u2aa1\u0338",notni:"\u220c",notniva:"\u220c",notnivb:"\u22fe",notnivc:"\u22fd",NotPrecedes:"\u2280",NotPrecedesEqual:"\u2aaf\u0338",NotPrecedesSlantEqual:"\u22e0",NotReverseElement:"\u220c",NotRightTriangleBar:"\u29d0\u0338",NotRightTriangle:"\u22eb",NotRightTriangleEqual:"\u22ed",NotSquareSubset:"\u228f\u0338",NotSquareSubsetEqual:"\u22e2",NotSquareSuperset:"\u2290\u0338",NotSquareSupersetEqual:"\u22e3",NotSubset:"\u2282\u20d2",NotSubsetEqual:"\u2288",NotSucceeds:"\u2281",NotSucceedsEqual:"\u2ab0\u0338",NotSucceedsSlantEqual:"\u22e1",NotSucceedsTilde:"\u227f\u0338",NotSuperset:"\u2283\u20d2",NotSupersetEqual:"\u2289",NotTilde:"\u2241",NotTildeEqual:"\u2244",NotTildeFullEqual:"\u2247",NotTildeTilde:"\u2249",NotVerticalBar:"\u2224",nparallel:"\u2226",npar:"\u2226",nparsl:"\u2afd\u20e5",npart:"\u2202\u0338",npolint:"\u2a14",npr:"\u2280",nprcue:"\u22e0",nprec:"\u2280",npreceq:"\u2aaf\u0338",npre:"\u2aaf\u0338",nrarrc:"\u2933\u0338",nrarr:"\u219b",nrArr:"\u21cf",nrarrw:"\u219d\u0338",nrightarrow:"\u219b",nRightarrow:"\u21cf",nrtri:"\u22eb",nrtrie:"\u22ed",nsc:"\u2281",nsccue:"\u22e1",nsce:"\u2ab0\u0338",Nscr:"\ud835\udca9",nscr:"\ud835\udcc3",nshortmid:"\u2224",nshortparallel:"\u2226",nsim:"\u2241",nsime:"\u2244",nsimeq:"\u2244",nsmid:"\u2224",nspar:"\u2226",nsqsube:"\u22e2",nsqsupe:"\u22e3",nsub:"\u2284",nsubE:"\u2ac5\u0338",nsube:"\u2288",nsubset:"\u2282\u20d2",nsubseteq:"\u2288",nsubseteqq:"\u2ac5\u0338",nsucc:"\u2281",nsucceq:"\u2ab0\u0338",nsup:"\u2285",nsupE:"\u2ac6\u0338",nsupe:"\u2289",nsupset:"\u2283\u20d2",nsupseteq:"\u2289",nsupseteqq:"\u2ac6\u0338",ntgl:"\u2279",Ntilde:"\xd1",ntilde:"\xf1",ntlg:"\u2278",ntriangleleft:"\u22ea",ntrianglelefteq:"\u22ec",ntriangleright:"\u22eb",ntrianglerighteq:"\u22ed",Nu:"\u039d",nu:"\u03bd",num:"#",numero:"\u2116",numsp:"\u2007",nvap:"\u224d\u20d2",nvdash:"\u22ac",nvDash:"\u22ad",nVdash:"\u22ae",nVDash:"\u22af",nvge:"\u2265\u20d2",nvgt:">\u20d2",nvHarr:"\u2904",nvinfin:"\u29de",nvlArr:"\u2902",nvle:"\u2264\u20d2",nvlt:"<\u20d2",nvltrie:"\u22b4\u20d2",nvrArr:"\u2903",nvrtrie:"\u22b5\u20d2",nvsim:"\u223c\u20d2",nwarhk:"\u2923",nwarr:"\u2196",nwArr:"\u21d6",nwarrow:"\u2196",nwnear:"\u2927",Oacute:"\xd3",oacute:"\xf3",oast:"\u229b",Ocirc:"\xd4",ocirc:"\xf4",ocir:"\u229a",Ocy:"\u041e",ocy:"\u043e",odash:"\u229d",Odblac:"\u0150",odblac:"\u0151",odiv:"\u2a38",odot:"\u2299",odsold:"\u29bc",OElig:"\u0152",oelig:"\u0153",ofcir:"\u29bf",Ofr:"\ud835\udd12",ofr:"\ud835\udd2c",ogon:"\u02db",Ograve:"\xd2",ograve:"\xf2",ogt:"\u29c1",ohbar:"\u29b5",ohm:"\u03a9",oint:"\u222e",olarr:"\u21ba",olcir:"\u29be",olcross:"\u29bb",oline:"\u203e",olt:"\u29c0",Omacr:"\u014c",omacr:"\u014d",Omega:"\u03a9",omega:"\u03c9",Omicron:"\u039f",omicron:"\u03bf",omid:"\u29b6",ominus:"\u2296",Oopf:"\ud835\udd46",oopf:"\ud835\udd60",opar:"\u29b7",OpenCurlyDoubleQuote:"\u201c",OpenCurlyQuote:"\u2018",operp:"\u29b9",oplus:"\u2295",orarr:"\u21bb",Or:"\u2a54",or:"\u2228",ord:"\u2a5d",order:"\u2134",orderof:"\u2134",ordf:"\xaa",ordm:"\xba",origof:"\u22b6",oror:"\u2a56",orslope:"\u2a57",orv:"\u2a5b",oS:"\u24c8",Oscr:"\ud835\udcaa",oscr:"\u2134",Oslash:"\xd8",oslash:"\xf8",osol:"\u2298",Otilde:"\xd5",otilde:"\xf5",otimesas:"\u2a36",Otimes:"\u2a37",otimes:"\u2297",Ouml:"\xd6",ouml:"\xf6",ovbar:"\u233d",OverBar:"\u203e",OverBrace:"\u23de",OverBracket:"\u23b4",OverParenthesis:"\u23dc",para:"\xb6",parallel:"\u2225",par:"\u2225",parsim:"\u2af3",parsl:"\u2afd",part:"\u2202",PartialD:"\u2202",Pcy:"\u041f",pcy:"\u043f",percnt:"%",period:".",permil:"\u2030",perp:"\u22a5",pertenk:"\u2031",Pfr:"\ud835\udd13",pfr:"\ud835\udd2d",Phi:"\u03a6",phi:"\u03c6",phiv:"\u03d5",phmmat:"\u2133",phone:"\u260e",Pi:"\u03a0",pi:"\u03c0",pitchfork:"\u22d4",piv:"\u03d6",planck:"\u210f",planckh:"\u210e",plankv:"\u210f",plusacir:"\u2a23",plusb:"\u229e",pluscir:"\u2a22",plus:"+",plusdo:"\u2214",plusdu:"\u2a25",pluse:"\u2a72",PlusMinus:"\xb1",plusmn:"\xb1",plussim:"\u2a26",plustwo:"\u2a27",pm:"\xb1",Poincareplane:"\u210c",pointint:"\u2a15",popf:"\ud835\udd61",Popf:"\u2119",pound:"\xa3",prap:"\u2ab7",Pr:"\u2abb",pr:"\u227a",prcue:"\u227c",precapprox:"\u2ab7",prec:"\u227a",preccurlyeq:"\u227c",Precedes:"\u227a",PrecedesEqual:"\u2aaf",PrecedesSlantEqual:"\u227c",PrecedesTilde:"\u227e",preceq:"\u2aaf",precnapprox:"\u2ab9",precneqq:"\u2ab5",precnsim:"\u22e8",pre:"\u2aaf",prE:"\u2ab3",precsim:"\u227e",prime:"\u2032",Prime:"\u2033",primes:"\u2119",prnap:"\u2ab9",prnE:"\u2ab5",prnsim:"\u22e8",prod:"\u220f",Product:"\u220f",profalar:"\u232e",profline:"\u2312",profsurf:"\u2313",prop:"\u221d",Proportional:"\u221d",Proportion:"\u2237",propto:"\u221d",prsim:"\u227e",prurel:"\u22b0",Pscr:"\ud835\udcab",pscr:"\ud835\udcc5",Psi:"\u03a8",psi:"\u03c8",puncsp:"\u2008",Qfr:"\ud835\udd14",qfr:"\ud835\udd2e",qint:"\u2a0c",qopf:"\ud835\udd62",Qopf:"\u211a",qprime:"\u2057",Qscr:"\ud835\udcac",qscr:"\ud835\udcc6",quaternions:"\u210d",quatint:"\u2a16",quest:"?",questeq:"\u225f",quot:'"',QUOT:'"',rAarr:"\u21db",race:"\u223d\u0331",Racute:"\u0154",racute:"\u0155",radic:"\u221a",raemptyv:"\u29b3",rang:"\u27e9",Rang:"\u27eb",rangd:"\u2992",range:"\u29a5",rangle:"\u27e9",raquo:"\xbb",rarrap:"\u2975",rarrb:"\u21e5",rarrbfs:"\u2920",rarrc:"\u2933",rarr:"\u2192",Rarr:"\u21a0",rArr:"\u21d2",rarrfs:"\u291e",rarrhk:"\u21aa",rarrlp:"\u21ac",rarrpl:"\u2945",rarrsim:"\u2974",Rarrtl:"\u2916",rarrtl:"\u21a3",rarrw:"\u219d",ratail:"\u291a",rAtail:"\u291c",ratio:"\u2236",rationals:"\u211a",rbarr:"\u290d",rBarr:"\u290f",RBarr:"\u2910",rbbrk:"\u2773",rbrace:"}",rbrack:"]",rbrke:"\u298c",rbrksld:"\u298e",rbrkslu:"\u2990",Rcaron:"\u0158",rcaron:"\u0159",Rcedil:"\u0156",rcedil:"\u0157",rceil:"\u2309",rcub:"}",Rcy:"\u0420",rcy:"\u0440",rdca:"\u2937",rdldhar:"\u2969",rdquo:"\u201d",rdquor:"\u201d",rdsh:"\u21b3",real:"\u211c",realine:"\u211b",realpart:"\u211c",reals:"\u211d",Re:"\u211c",rect:"\u25ad",reg:"\xae",REG:"\xae",ReverseElement:"\u220b",ReverseEquilibrium:"\u21cb",ReverseUpEquilibrium:"\u296f",rfisht:"\u297d",rfloor:"\u230b",rfr:"\ud835\udd2f",Rfr:"\u211c",rHar:"\u2964",rhard:"\u21c1",rharu:"\u21c0",rharul:"\u296c",Rho:"\u03a1",rho:"\u03c1",rhov:"\u03f1",RightAngleBracket:"\u27e9",RightArrowBar:"\u21e5",rightarrow:"\u2192",RightArrow:"\u2192",Rightarrow:"\u21d2",RightArrowLeftArrow:"\u21c4",rightarrowtail:"\u21a3",RightCeiling:"\u2309",RightDoubleBracket:"\u27e7",RightDownTeeVector:"\u295d",RightDownVectorBar:"\u2955",RightDownVector:"\u21c2",RightFloor:"\u230b",rightharpoondown:"\u21c1",rightharpoonup:"\u21c0",rightleftarrows:"\u21c4",rightleftharpoons:"\u21cc",rightrightarrows:"\u21c9",rightsquigarrow:"\u219d",RightTeeArrow:"\u21a6",RightTee:"\u22a2",RightTeeVector:"\u295b",rightthreetimes:"\u22cc",RightTriangleBar:"\u29d0",RightTriangle:"\u22b3",RightTriangleEqual:"\u22b5",RightUpDownVector:"\u294f",RightUpTeeVector:"\u295c",RightUpVectorBar:"\u2954",RightUpVector:"\u21be",RightVectorBar:"\u2953",RightVector:"\u21c0",ring:"\u02da",risingdotseq:"\u2253",rlarr:"\u21c4",rlhar:"\u21cc",rlm:"\u200f",rmoustache:"\u23b1",rmoust:"\u23b1",rnmid:"\u2aee",roang:"\u27ed",roarr:"\u21fe",robrk:"\u27e7",ropar:"\u2986",ropf:"\ud835\udd63",Ropf:"\u211d",roplus:"\u2a2e",rotimes:"\u2a35",RoundImplies:"\u2970",rpar:")",rpargt:"\u2994",rppolint:"\u2a12",rrarr:"\u21c9",Rrightarrow:"\u21db",rsaquo:"\u203a",rscr:"\ud835\udcc7",Rscr:"\u211b",rsh:"\u21b1",Rsh:"\u21b1",rsqb:"]",rsquo:"\u2019",rsquor:"\u2019",rthree:"\u22cc",rtimes:"\u22ca",rtri:"\u25b9",rtrie:"\u22b5",rtrif:"\u25b8",rtriltri:"\u29ce",RuleDelayed:"\u29f4",ruluhar:"\u2968",rx:"\u211e",Sacute:"\u015a",sacute:"\u015b",sbquo:"\u201a",scap:"\u2ab8",Scaron:"\u0160",scaron:"\u0161",Sc:"\u2abc",sc:"\u227b",sccue:"\u227d",sce:"\u2ab0",scE:"\u2ab4",Scedil:"\u015e",scedil:"\u015f",Scirc:"\u015c",scirc:"\u015d",scnap:"\u2aba",scnE:"\u2ab6",scnsim:"\u22e9",scpolint:"\u2a13",scsim:"\u227f",Scy:"\u0421",scy:"\u0441",sdotb:"\u22a1",sdot:"\u22c5",sdote:"\u2a66",searhk:"\u2925",searr:"\u2198",seArr:"\u21d8",searrow:"\u2198",sect:"\xa7",semi:";",seswar:"\u2929",setminus:"\u2216",setmn:"\u2216",sext:"\u2736",Sfr:"\ud835\udd16",sfr:"\ud835\udd30",sfrown:"\u2322",sharp:"\u266f",SHCHcy:"\u0429",shchcy:"\u0449",SHcy:"\u0428",shcy:"\u0448",ShortDownArrow:"\u2193",ShortLeftArrow:"\u2190",shortmid:"\u2223",shortparallel:"\u2225",ShortRightArrow:"\u2192",ShortUpArrow:"\u2191",shy:"\xad",Sigma:"\u03a3",sigma:"\u03c3",sigmaf:"\u03c2",sigmav:"\u03c2",sim:"\u223c",simdot:"\u2a6a",sime:"\u2243",simeq:"\u2243",simg:"\u2a9e",simgE:"\u2aa0",siml:"\u2a9d",simlE:"\u2a9f",simne:"\u2246",simplus:"\u2a24",simrarr:"\u2972",slarr:"\u2190",SmallCircle:"\u2218",smallsetminus:"\u2216",smashp:"\u2a33",smeparsl:"\u29e4",smid:"\u2223",smile:"\u2323",smt:"\u2aaa",smte:"\u2aac",smtes:"\u2aac\ufe00",SOFTcy:"\u042c",softcy:"\u044c",solbar:"\u233f",solb:"\u29c4",sol:"/",Sopf:"\ud835\udd4a",sopf:"\ud835\udd64",spades:"\u2660",spadesuit:"\u2660",spar:"\u2225",sqcap:"\u2293",sqcaps:"\u2293\ufe00",sqcup:"\u2294",sqcups:"\u2294\ufe00",Sqrt:"\u221a",sqsub:"\u228f",sqsube:"\u2291",sqsubset:"\u228f",sqsubseteq:"\u2291",sqsup:"\u2290",sqsupe:"\u2292",sqsupset:"\u2290",sqsupseteq:"\u2292",square:"\u25a1",Square:"\u25a1",SquareIntersection:"\u2293",SquareSubset:"\u228f",SquareSubsetEqual:"\u2291",SquareSuperset:"\u2290",SquareSupersetEqual:"\u2292",SquareUnion:"\u2294",squarf:"\u25aa",squ:"\u25a1",squf:"\u25aa",srarr:"\u2192",Sscr:"\ud835\udcae",sscr:"\ud835\udcc8",ssetmn:"\u2216",ssmile:"\u2323",sstarf:"\u22c6",Star:"\u22c6",star:"\u2606",starf:"\u2605",straightepsilon:"\u03f5",straightphi:"\u03d5",strns:"\xaf",sub:"\u2282",Sub:"\u22d0",subdot:"\u2abd",subE:"\u2ac5",sube:"\u2286",subedot:"\u2ac3",submult:"\u2ac1",subnE:"\u2acb",subne:"\u228a",subplus:"\u2abf",subrarr:"\u2979",subset:"\u2282",Subset:"\u22d0",subseteq:"\u2286",subseteqq:"\u2ac5",SubsetEqual:"\u2286",subsetneq:"\u228a",subsetneqq:"\u2acb",subsim:"\u2ac7",subsub:"\u2ad5",subsup:"\u2ad3",succapprox:"\u2ab8",succ:"\u227b",succcurlyeq:"\u227d",Succeeds:"\u227b",SucceedsEqual:"\u2ab0",SucceedsSlantEqual:"\u227d",SucceedsTilde:"\u227f",succeq:"\u2ab0",succnapprox:"\u2aba",succneqq:"\u2ab6",succnsim:"\u22e9",succsim:"\u227f",SuchThat:"\u220b",sum:"\u2211",Sum:"\u2211",sung:"\u266a",sup1:"\xb9",sup2:"\xb2",sup3:"\xb3",sup:"\u2283",Sup:"\u22d1",supdot:"\u2abe",supdsub:"\u2ad8",supE:"\u2ac6",supe:"\u2287",supedot:"\u2ac4",Superset:"\u2283",SupersetEqual:"\u2287",suphsol:"\u27c9",suphsub:"\u2ad7",suplarr:"\u297b",supmult:"\u2ac2",supnE:"\u2acc",supne:"\u228b",supplus:"\u2ac0",supset:"\u2283",Supset:"\u22d1",supseteq:"\u2287",supseteqq:"\u2ac6",supsetneq:"\u228b",supsetneqq:"\u2acc",supsim:"\u2ac8",supsub:"\u2ad4",supsup:"\u2ad6",swarhk:"\u2926",swarr:"\u2199",swArr:"\u21d9",swarrow:"\u2199",swnwar:"\u292a",szlig:"\xdf",Tab:"\t",target:"\u2316",Tau:"\u03a4",tau:"\u03c4",tbrk:"\u23b4",Tcaron:"\u0164",tcaron:"\u0165",Tcedil:"\u0162",tcedil:"\u0163",Tcy:"\u0422",tcy:"\u0442",tdot:"\u20db",telrec:"\u2315",Tfr:"\ud835\udd17",tfr:"\ud835\udd31",there4:"\u2234",therefore:"\u2234",Therefore:"\u2234",Theta:"\u0398",theta:"\u03b8",thetasym:"\u03d1",thetav:"\u03d1",thickapprox:"\u2248",thicksim:"\u223c",ThickSpace:"\u205f\u200a",ThinSpace:"\u2009",thinsp:"\u2009",thkap:"\u2248",thksim:"\u223c",THORN:"\xde",thorn:"\xfe",tilde:"\u02dc",Tilde:"\u223c",TildeEqual:"\u2243",TildeFullEqual:"\u2245",TildeTilde:"\u2248",timesbar:"\u2a31",timesb:"\u22a0",times:"\xd7",timesd:"\u2a30",tint:"\u222d",toea:"\u2928",topbot:"\u2336",topcir:"\u2af1",top:"\u22a4",Topf:"\ud835\udd4b",topf:"\ud835\udd65",topfork:"\u2ada",tosa:"\u2929",tprime:"\u2034",trade:"\u2122",TRADE:"\u2122",triangle:"\u25b5",triangledown:"\u25bf",triangleleft:"\u25c3",trianglelefteq:"\u22b4",triangleq:"\u225c",triangleright:"\u25b9",trianglerighteq:"\u22b5",tridot:"\u25ec",trie:"\u225c",triminus:"\u2a3a",TripleDot:"\u20db",triplus:"\u2a39",trisb:"\u29cd",tritime:"\u2a3b",trpezium:"\u23e2",Tscr:"\ud835\udcaf",tscr:"\ud835\udcc9",TScy:"\u0426",tscy:"\u0446",TSHcy:"\u040b",tshcy:"\u045b",Tstrok:"\u0166",tstrok:"\u0167",twixt:"\u226c",twoheadleftarrow:"\u219e",twoheadrightarrow:"\u21a0",Uacute:"\xda",uacute:"\xfa",uarr:"\u2191",Uarr:"\u219f",uArr:"\u21d1",Uarrocir:"\u2949",Ubrcy:"\u040e",ubrcy:"\u045e",Ubreve:"\u016c",ubreve:"\u016d",Ucirc:"\xdb",ucirc:"\xfb",Ucy:"\u0423",ucy:"\u0443",udarr:"\u21c5",Udblac:"\u0170",udblac:"\u0171",udhar:"\u296e",ufisht:"\u297e",Ufr:"\ud835\udd18",ufr:"\ud835\udd32",Ugrave:"\xd9",ugrave:"\xf9",uHar:"\u2963",uharl:"\u21bf",uharr:"\u21be",uhblk:"\u2580",ulcorn:"\u231c",ulcorner:"\u231c",ulcrop:"\u230f",ultri:"\u25f8",Umacr:"\u016a",umacr:"\u016b",uml:"\xa8",UnderBar:"_",UnderBrace:"\u23df",UnderBracket:"\u23b5",UnderParenthesis:"\u23dd",Union:"\u22c3",UnionPlus:"\u228e",Uogon:"\u0172",uogon:"\u0173",Uopf:"\ud835\udd4c",uopf:"\ud835\udd66",UpArrowBar:"\u2912",uparrow:"\u2191",UpArrow:"\u2191",Uparrow:"\u21d1",UpArrowDownArrow:"\u21c5",updownarrow:"\u2195",UpDownArrow:"\u2195",Updownarrow:"\u21d5",UpEquilibrium:"\u296e",upharpoonleft:"\u21bf",upharpoonright:"\u21be",uplus:"\u228e",UpperLeftArrow:"\u2196",UpperRightArrow:"\u2197",upsi:"\u03c5",Upsi:"\u03d2",upsih:"\u03d2",Upsilon:"\u03a5",upsilon:"\u03c5",UpTeeArrow:"\u21a5",UpTee:"\u22a5",upuparrows:"\u21c8",urcorn:"\u231d",urcorner:"\u231d",urcrop:"\u230e",Uring:"\u016e",uring:"\u016f",urtri:"\u25f9",Uscr:"\ud835\udcb0",uscr:"\ud835\udcca",utdot:"\u22f0",Utilde:"\u0168",utilde:"\u0169",utri:"\u25b5",utrif:"\u25b4",uuarr:"\u21c8",Uuml:"\xdc",uuml:"\xfc",uwangle:"\u29a7",vangrt:"\u299c",varepsilon:"\u03f5",varkappa:"\u03f0",varnothing:"\u2205",varphi:"\u03d5",varpi:"\u03d6",varpropto:"\u221d",varr:"\u2195",vArr:"\u21d5",varrho:"\u03f1",varsigma:"\u03c2",varsubsetneq:"\u228a\ufe00",varsubsetneqq:"\u2acb\ufe00",varsupsetneq:"\u228b\ufe00",varsupsetneqq:"\u2acc\ufe00",vartheta:"\u03d1",vartriangleleft:"\u22b2",vartriangleright:"\u22b3",vBar:"\u2ae8",Vbar:"\u2aeb",vBarv:"\u2ae9",Vcy:"\u0412",vcy:"\u0432",vdash:"\u22a2",vDash:"\u22a8",Vdash:"\u22a9",VDash:"\u22ab",Vdashl:"\u2ae6",veebar:"\u22bb",vee:"\u2228",Vee:"\u22c1",veeeq:"\u225a",vellip:"\u22ee",verbar:"|",Verbar:"\u2016",vert:"|",Vert:"\u2016",VerticalBar:"\u2223",VerticalLine:"|",VerticalSeparator:"\u2758",VerticalTilde:"\u2240",VeryThinSpace:"\u200a",Vfr:"\ud835\udd19",vfr:"\ud835\udd33",vltri:"\u22b2",vnsub:"\u2282\u20d2",vnsup:"\u2283\u20d2",Vopf:"\ud835\udd4d",vopf:"\ud835\udd67",vprop:"\u221d",vrtri:"\u22b3",Vscr:"\ud835\udcb1",vscr:"\ud835\udccb",vsubnE:"\u2acb\ufe00",vsubne:"\u228a\ufe00",vsupnE:"\u2acc\ufe00",vsupne:"\u228b\ufe00",Vvdash:"\u22aa",vzigzag:"\u299a",Wcirc:"\u0174",wcirc:"\u0175",wedbar:"\u2a5f",wedge:"\u2227",Wedge:"\u22c0",wedgeq:"\u2259",weierp:"\u2118",Wfr:"\ud835\udd1a",wfr:"\ud835\udd34",Wopf:"\ud835\udd4e",wopf:"\ud835\udd68",wp:"\u2118",wr:"\u2240",wreath:"\u2240",Wscr:"\ud835\udcb2",wscr:"\ud835\udccc",xcap:"\u22c2",xcirc:"\u25ef",xcup:"\u22c3",xdtri:"\u25bd",Xfr:"\ud835\udd1b",xfr:"\ud835\udd35",xharr:"\u27f7",xhArr:"\u27fa",Xi:"\u039e",xi:"\u03be",xlarr:"\u27f5",xlArr:"\u27f8",xmap:"\u27fc",xnis:"\u22fb",xodot:"\u2a00",Xopf:"\ud835\udd4f",xopf:"\ud835\udd69",xoplus:"\u2a01",xotime:"\u2a02",xrarr:"\u27f6",xrArr:"\u27f9",Xscr:"\ud835\udcb3",xscr:"\ud835\udccd",xsqcup:"\u2a06",xuplus:"\u2a04",xutri:"\u25b3",xvee:"\u22c1",xwedge:"\u22c0",Yacute:"\xdd",yacute:"\xfd",YAcy:"\u042f",yacy:"\u044f",Ycirc:"\u0176",ycirc:"\u0177",Ycy:"\u042b",ycy:"\u044b",yen:"\xa5",Yfr:"\ud835\udd1c",yfr:"\ud835\udd36",YIcy:"\u0407",yicy:"\u0457",Yopf:"\ud835\udd50",yopf:"\ud835\udd6a",Yscr:"\ud835\udcb4",yscr:"\ud835\udcce",YUcy:"\u042e",yucy:"\u044e",yuml:"\xff",Yuml:"\u0178",Zacute:"\u0179",zacute:"\u017a",Zcaron:"\u017d",zcaron:"\u017e",Zcy:"\u0417",zcy:"\u0437",Zdot:"\u017b",zdot:"\u017c",zeetrf:"\u2128",ZeroWidthSpace:"\u200b",Zeta:"\u0396",zeta:"\u03b6",zfr:"\ud835\udd37",Zfr:"\u2128",ZHcy:"\u0416",zhcy:"\u0436",zigrarr:"\u21dd",zopf:"\ud835\udd6b",Zopf:"\u2124",Zscr:"\ud835\udcb5",zscr:"\ud835\udccf",zwj:"\u200d",zwnj:"\u200c"}},{}],53:[function(e,r,t){"use strict";function n(e){return Array.prototype.slice.call(arguments,1).forEach(function(r){r&&Object.keys(r).forEach(function(t){e[t]=r[t]})}),e}function s(e){return Object.prototype.toString.call(e)}function o(e){return"[object String]"===s(e)}function i(e){return"[object Object]"===s(e)}function a(e){return"[object RegExp]"===s(e)}function c(e){return"[object Function]"===s(e)}function l(e){return e.replace(/[.?*+^$[\]\\(){}|-]/g,"\\$&")}function u(e){return Object.keys(e||{}).reduce(function(e,r){return e||b.hasOwnProperty(r)},!1)}function p(e){e.__index__=-1,e.__text_cache__=""}function h(e){return function(r,t){var n=r.slice(t);return e.test(n)?n.match(e)[0].length:0}}function f(){return function(e,r){r.normalize(e)}}function d(r){function t(e){return e.replace("%TLDS%",s.src_tlds)}function n(e,r){throw new Error('(LinkifyIt) Invalid schema "'+e+'": '+r)}var s=r.re=e("./lib/re")(r.__opts__),u=r.__tlds__.slice();r.onCompile(),r.__tlds_replaced__||u.push("a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvwxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eosuw]|s[abcdeghijklmnortuvxyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[et]|z[amw]"),u.push(s.src_xn),s.src_tlds=u.join("|"),s.email_fuzzy=RegExp(t(s.tpl_email_fuzzy),"i"),s.link_fuzzy=RegExp(t(s.tpl_link_fuzzy),"i"),s.link_no_ip_fuzzy=RegExp(t(s.tpl_link_no_ip_fuzzy),"i"),s.host_fuzzy_test=RegExp(t(s.tpl_host_fuzzy_test),"i");var d=[];r.__compiled__={},Object.keys(r.__schemas__).forEach(function(e){var t=r.__schemas__[e];if(null!==t){var s={validate:null,link:null};return r.__compiled__[e]=s,i(t)?(a(t.validate)?s.validate=h(t.validate):c(t.validate)?s.validate=t.validate:n(e,t),void(c(t.normalize)?s.normalize=t.normalize:t.normalize?n(e,t):s.normalize=f())):o(t)?void d.push(e):void n(e,t)}}),d.forEach(function(e){r.__compiled__[r.__schemas__[e]]&&(r.__compiled__[e].validate=r.__compiled__[r.__schemas__[e]].validate,r.__compiled__[e].normalize=r.__compiled__[r.__schemas__[e]].normalize)}),r.__compiled__[""]={validate:null,normalize:f()};var m=Object.keys(r.__compiled__).filter(function(e){return e.length>0&&r.__compiled__[e]}).map(l).join("|");r.re.schema_test=RegExp("(^|(?!_)(?:[><\uff5c]|"+s.src_ZPCc+"))("+m+")","i"),r.re.schema_search=RegExp("(^|(?!_)(?:[><\uff5c]|"+s.src_ZPCc+"))("+m+")","ig"),r.re.pretest=RegExp("("+r.re.schema_test.source+")|("+r.re.host_fuzzy_test.source+")|@","i"),p(r)}function m(e,r){var t=e.__index__,n=e.__last_index__,s=e.__text_cache__.slice(t,n);this.schema=e.__schema__.toLowerCase(),this.index=t+r,this.lastIndex=n+r,this.raw=s,this.text=s,this.url=s}function _(e,r){var t=new m(e,r);return e.__compiled__[t.schema].normalize(t,e),t}function g(e,r){if(!(this instanceof g))return new g(e,r);r||u(e)&&(r=e,e={}),this.__opts__=n({},b,r),this.__index__=-1,this.__last_index__=-1,this.__schema__="",this.__text_cache__="",this.__schemas__=n({},k,e),this.__compiled__={},this.__tlds__=v,this.__tlds_replaced__=!1,this.re={},d(this)}var b={fuzzyLink:!0,fuzzyEmail:!0,fuzzyIP:!1},k={"http:":{validate:function(e,r,t){var n=e.slice(r);return t.re.http||(t.re.http=new RegExp("^\\/\\/"+t.re.src_auth+t.re.src_host_port_strict+t.re.src_path,"i")),t.re.http.test(n)?n.match(t.re.http)[0].length:0}},"https:":"http:","ftp:":"http:","//":{validate:function(e,r,t){var n=e.slice(r);return t.re.no_http||(t.re.no_http=new RegExp("^"+t.re.src_auth+"(?:localhost|(?:(?:"+t.re.src_domain+")\\.)+"+t.re.src_domain_root+")"+t.re.src_port+t.re.src_host_terminator+t.re.src_path,"i")),t.re.no_http.test(n)?r>=3&&":"===e[r-3]?0:r>=3&&"/"===e[r-3]?0:n.match(t.re.no_http)[0].length:0}},"mailto:":{validate:function(e,r,t){var n=e.slice(r);return t.re.mailto||(t.re.mailto=new RegExp("^"+t.re.src_email_name+"@"+t.re.src_host_strict,"i")),t.re.mailto.test(n)?n.match(t.re.mailto)[0].length:0}}},v="biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|\u0440\u0444".split("|");g.prototype.add=function(e,r){return this.__schemas__[e]=r,d(this),this},g.prototype.set=function(e){return this.__opts__=n(this.__opts__,e),this},g.prototype.test=function(e){if(this.__text_cache__=e,this.__index__=-1,!e.length)return!1;var r,t,n,s,o,i,a,c;if(this.re.schema_test.test(e))for(a=this.re.schema_search,a.lastIndex=0;null!==(r=a.exec(e));)if(s=this.testSchemaAt(e,r[2],a.lastIndex)){this.__schema__=r[2],this.__index__=r.index+r[1].length,this.__last_index__=r.index+r[0].length+s;break}return this.__opts__.fuzzyLink&&this.__compiled__["http:"]&&(c=e.search(this.re.host_fuzzy_test))>=0&&(this.__index__<0||c=0&&null!==(n=e.match(this.re.email_fuzzy))&&(o=n.index+n[1].length,i=n.index+n[0].length,(this.__index__<0||othis.__last_index__)&&(this.__schema__="mailto:",this.__index__=o,this.__last_index__=i)),this.__index__>=0},g.prototype.pretest=function(e){return this.re.pretest.test(e)},g.prototype.testSchemaAt=function(e,r,t){return this.__compiled__[r.toLowerCase()]?this.__compiled__[r.toLowerCase()].validate(e,t,this):0},g.prototype.match=function(e){var r=0,t=[];this.__index__>=0&&this.__text_cache__===e&&(t.push(_(this,r)),r=this.__last_index__);for(var n=r?e.slice(r):e;this.test(n);)t.push(_(this,r)),n=n.slice(this.__last_index__),r+=this.__last_index__;return t.length?t:null},g.prototype.tlds=function(e,r){return e=Array.isArray(e)?e:[e],r?(this.__tlds__=this.__tlds__.concat(e).sort().filter(function(e,r,t){return e!==t[r-1]}).reverse(),d(this),this):(this.__tlds__=e.slice(),this.__tlds_replaced__=!0,d(this),this)},g.prototype.normalize=function(e){e.schema||(e.url="http://"+e.url),"mailto:"!==e.schema||/^mailto:/i.test(e.url)||(e.url="mailto:"+e.url)},g.prototype.onCompile=function(){},r.exports=g},{"./lib/re":54}],54:[function(e,r,t){"use strict";r.exports=function(r){var t={};t.src_Any=e("uc.micro/properties/Any/regex").source,t.src_Cc=e("uc.micro/categories/Cc/regex").source,t.src_Z=e("uc.micro/categories/Z/regex").source,t.src_P=e("uc.micro/categories/P/regex").source,t.src_ZPCc=[t.src_Z,t.src_P,t.src_Cc].join("|"),t.src_ZCc=[t.src_Z,t.src_Cc].join("|");return t.src_pseudo_letter="(?:(?![><\uff5c]|"+t.src_ZPCc+")"+t.src_Any+")",t.src_ip4="(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",t.src_auth="(?:(?:(?!"+t.src_ZCc+"|[@/\\[\\]()]).)+@)?",t.src_port="(?::(?:6(?:[0-4]\\d{3}|5(?:[0-4]\\d{2}|5(?:[0-2]\\d|3[0-5])))|[1-5]?\\d{1,4}))?",t.src_host_terminator="(?=$|[><\uff5c]|"+t.src_ZPCc+")(?!-|_|:\\d|\\.-|\\.(?!$|"+t.src_ZPCc+"))",t.src_path="(?:[/?#](?:(?!"+t.src_ZCc+"|[><\uff5c]|[()[\\]{}.,\"'?!\\-]).|\\[(?:(?!"+t.src_ZCc+"|\\]).)*\\]|\\((?:(?!"+t.src_ZCc+"|[)]).)*\\)|\\{(?:(?!"+t.src_ZCc+'|[}]).)*\\}|\\"(?:(?!'+t.src_ZCc+'|["]).)+\\"|\\\'(?:(?!'+t.src_ZCc+"|[']).)+\\'|\\'(?="+t.src_pseudo_letter+"|[-]).|\\.{2,3}[a-zA-Z0-9%/]|\\.(?!"+t.src_ZCc+"|[.]).|"+(r&&r["---"]?"\\-(?!--(?:[^-]|$))(?:-*)|":"\\-+|")+"\\,(?!"+t.src_ZCc+").|\\!(?!"+t.src_ZCc+"|[!]).|\\?(?!"+t.src_ZCc+"|[?]).)+|\\/)?",t.src_email_name='[\\-;:&=\\+\\$,\\"\\.a-zA-Z0-9_]+',t.src_xn="xn--[a-z0-9\\-]{1,59}",t.src_domain_root="(?:"+t.src_xn+"|"+t.src_pseudo_letter+"{1,63})",t.src_domain="(?:"+t.src_xn+"|(?:"+t.src_pseudo_letter+")|(?:"+t.src_pseudo_letter+"(?:-(?!-)|"+t.src_pseudo_letter+"){0,61}"+t.src_pseudo_letter+"))",t.src_host="(?:(?:(?:(?:"+t.src_domain+")\\.)*"+t.src_domain+"))",t.tpl_host_fuzzy="(?:"+t.src_ip4+"|(?:(?:(?:"+t.src_domain+")\\.)+(?:%TLDS%)))",t.tpl_host_no_ip_fuzzy="(?:(?:(?:"+t.src_domain+")\\.)+(?:%TLDS%))",t.src_host_strict=t.src_host+t.src_host_terminator,t.tpl_host_fuzzy_strict=t.tpl_host_fuzzy+t.src_host_terminator,t.src_host_port_strict=t.src_host+t.src_port+t.src_host_terminator,t.tpl_host_port_fuzzy_strict=t.tpl_host_fuzzy+t.src_port+t.src_host_terminator,t.tpl_host_port_no_ip_fuzzy_strict=t.tpl_host_no_ip_fuzzy+t.src_port+t.src_host_terminator,t.tpl_host_fuzzy_test="localhost|www\\.|\\.\\d{1,3}\\.|(?:\\.(?:%TLDS%)(?:"+t.src_ZPCc+"|>|$))",t.tpl_email_fuzzy="(^|[><\uff5c]|\\(|"+t.src_ZCc+")("+t.src_email_name+"@"+t.tpl_host_fuzzy_strict+")",t.tpl_link_fuzzy="(^|(?![.:/\\-_@])(?:[$+<=>^`|\uff5c]|"+t.src_ZPCc+"))((?![$+<=>^`|\uff5c])"+t.tpl_host_port_fuzzy_strict+t.src_path+")",t.tpl_link_no_ip_fuzzy="(^|(?![.:/\\-_@])(?:[$+<=>^`|\uff5c]|"+t.src_ZPCc+"))((?![$+<=>^`|\uff5c])"+t.tpl_host_port_no_ip_fuzzy_strict+t.src_path+")",t}},{ -"uc.micro/categories/Cc/regex":61,"uc.micro/categories/P/regex":63,"uc.micro/categories/Z/regex":64,"uc.micro/properties/Any/regex":66}],55:[function(e,r,t){"use strict";function n(e){var r,t,n=o[e];if(n)return n;for(n=o[e]=[],r=0;r<128;r++)t=String.fromCharCode(r),n.push(t);for(r=0;r=55296&&c<=57343?"\ufffd\ufffd\ufffd":String.fromCharCode(c),r+=6):240==(248&s)&&r+91114111?l+="\ufffd\ufffd\ufffd\ufffd":(c-=65536,l+=String.fromCharCode(55296+(c>>10),56320+(1023&c))),r+=9):l+="\ufffd";return l})}var o={};s.defaultChars=";/?:@&=+$,#",s.componentChars="",r.exports=s},{}],56:[function(e,r,t){"use strict";function n(e){var r,t,n=o[e];if(n)return n;for(n=o[e]=[],r=0;r<128;r++)t=String.fromCharCode(r),/^[0-9a-z]$/i.test(t)?n.push(t):n.push("%"+("0"+r.toString(16).toUpperCase()).slice(-2));for(r=0;r=55296&&a<=57343){if(a>=55296&&a<=56319&&o+1=56320&&c<=57343){u+=encodeURIComponent(e[o]+e[o+1]),o++;continue}u+="%EF%BF%BD"}else u+=encodeURIComponent(e[o]);return u}var o={};s.defaultChars=";/?:@&=+$,-_.!~*'()#",s.componentChars="-_.!~*'()",r.exports=s},{}],57:[function(e,r,t){"use strict";r.exports=function(e){var r="";return r+=e.protocol||"",r+=e.slashes?"//":"",r+=e.auth?e.auth+"@":"",r+=e.hostname&&e.hostname.indexOf(":")!==-1?"["+e.hostname+"]":e.hostname||"",r+=e.port?":"+e.port:"",r+=e.pathname||"",r+=e.search||"",r+=e.hash||""}},{}],58:[function(e,r,t){"use strict";r.exports.encode=e("./encode"),r.exports.decode=e("./decode"),r.exports.format=e("./format"),r.exports.parse=e("./parse")},{"./decode":55,"./encode":56,"./format":57,"./parse":59}],59:[function(e,r,t){"use strict";function n(){this.protocol=null,this.slashes=null,this.auth=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.pathname=null}function s(e,r){if(e&&e instanceof n)return e;var t=new n;return t.parse(e,r),t}var o=/^([a-z0-9.+-]+:)/i,i=/:[0-9]*$/,a=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,c=["<",">",'"',"`"," ","\r","\n","\t"],l=["{","}","|","\\","^","`"].concat(c),u=["'"].concat(l),p=["%","/","?",";","#"].concat(u),h=["/","?","#"],f={javascript:!0,"javascript:":!0},d={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0};n.prototype.parse=function(e,r){var t,n,s,i,c,l=e;if(l=l.trim(),!r&&1===e.split("#").length){var u=a.exec(l);if(u)return this.pathname=u[1],u[2]&&(this.search=u[2]),this}var m=o.exec(l);if(m&&(m=m[0],s=m.toLowerCase(),this.protocol=m,l=l.substr(m.length)),(r||m||l.match(/^\/\/[^@\/]+@[^@\/]+/))&&(!(c="//"===l.substr(0,2))||m&&f[m]||(l=l.substr(2),this.slashes=!0)),!f[m]&&(c||m&&!d[m])){var _=-1;for(t=0;t127?"x":x[A];if(!C.match(/^[+a-z0-9A-Z_-]{0,63}$/)){var D=y.slice(0,t),q=y.slice(t+1),E=x.match(/^([+a-z0-9A-Z_-]{0,63})(.*)$/);E&&(D.push(E[1]),q.unshift(E[2])),q.length&&(l=q.join(".")+l),this.hostname=D.join(".");break}}}}this.hostname.length>255&&(this.hostname=""),v&&(this.hostname=this.hostname.substr(1,this.hostname.length-2))}var S=l.indexOf("#");S!==-1&&(this.hash=l.substr(S),l=l.slice(0,S));var F=l.indexOf("?");return F!==-1&&(this.search=l.substr(F),l=l.slice(0,F)),l&&(this.pathname=l),d[s]&&this.hostname&&!this.pathname&&(this.pathname=""),this},n.prototype.parseHost=function(e){var r=i.exec(e);r&&(r=r[0],":"!==r&&(this.port=r.substr(1)),e=e.substr(0,e.length-r.length)),e&&(this.hostname=e)},r.exports=s},{}],60:[function(r,t,n){(function(r){!function(s){function o(e){throw new RangeError(w[e])}function i(e,r){for(var t=e.length,n=[];t--;)n[t]=r(e[t]);return n}function a(e,r){var t=e.split("@"),n="";return t.length>1&&(n=t[0]+"@",e=t[1]),e=e.replace(/[\x2E\u3002\uFF0E\uFF61]/g,"."),n+i(e.split("."),r).join(".")}function c(e){for(var r,t,n=[],s=0,o=e.length;s=55296&&r<=56319&&s65535&&(e-=65536,r+=q(e>>>10&1023|55296),e=56320|1023&e),r+=q(e)}).join("")}function u(e){return e-48<10?e-22:e-65<26?e-65:e-97<26?e-97:36}function p(e,r){return e+22+75*(e<26)-((0!=r)<<5)}function h(e,r,t){var n=0;for(e=t?D(e/700):e>>1,e+=D(e/r);e>455;n+=36)e=D(e/35);return D(n+36*e/(e+38))}function f(e){var r,t,n,s,i,a,c,p,f,d,m=[],_=e.length,g=0,b=128,k=72;for(t=e.lastIndexOf("-"),t<0&&(t=0),n=0;n=128&&o("not-basic"),m.push(e.charCodeAt(n));for(s=t>0?t+1:0;s<_;){for(i=g,a=1,c=36;s>=_&&o("invalid-input"),p=u(e.charCodeAt(s++)),(p>=36||p>D((x-g)/a))&&o("overflow"),g+=p*a,f=c<=k?1:c>=k+26?26:c-k,!(pD(x/d)&&o("overflow"),a*=d;r=m.length+1,k=h(g-i,r,0==i),D(g/r)>x-b&&o("overflow"),b+=D(g/r),g%=r,m.splice(g++,0,b)}return l(m)}function d(e){var r,t,n,s,i,a,l,u,f,d,m,_,g,b,k,v=[];for(e=c(e),_=e.length,r=128,t=0,i=72,a=0;a<_;++a)(m=e[a])<128&&v.push(q(m));for(n=s=v.length,s&&v.push("-");n<_;){for(l=x,a=0;a<_;++a)(m=e[a])>=r&&mD((x-t)/g)&&o("overflow"),t+=(l-r)*g,r=l,a=0;a<_;++a)if(m=e[a],mx&&o("overflow"),m==r){for(u=t,f=36;d=f<=i?1:f>=i+26?26:f-i,!(u= 0x80 (not a basic code point)","invalid-input":"Invalid input"},D=Math.floor,q=String.fromCharCode;if(v={version:"1.4.1",ucs2:{decode:c,encode:l},decode:f,encode:d,toASCII:_,toUnicode:m},"function"==typeof e&&"object"==typeof e.amd&&e.amd)e("punycode",function(){return v});else if(g&&b)if(t.exports==g)b.exports=v;else for(y in v)v.hasOwnProperty(y)&&(g[y]=v[y]);else s.punycode=v}(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],61:[function(e,r,t){r.exports=/[\0-\x1F\x7F-\x9F]/},{}],62:[function(e,r,t){r.exports=/[\xAD\u0600-\u0605\u061C\u06DD\u070F\u08E2\u180E\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u206F\uFEFF\uFFF9-\uFFFB]|\uD804\uDCBD|\uD82F[\uDCA0-\uDCA3]|\uD834[\uDD73-\uDD7A]|\uDB40[\uDC01\uDC20-\uDC7F]/},{}],63:[function(e,r,t){r.exports=/[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E44\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC9\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDC4B-\uDC4F\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDF3C-\uDF3E]|\uD807[\uDC41-\uDC45\uDC70\uDC71]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD83A[\uDD5E\uDD5F]/},{}],64:[function(e,r,t){r.exports=/[ \xA0\u1680\u2000-\u200A\u202F\u205F\u3000]/},{}],65:[function(e,r,t){"use strict";t.Any=e("./properties/Any/regex"),t.Cc=e("./categories/Cc/regex"),t.Cf=e("./categories/Cf/regex"),t.P=e("./categories/P/regex"),t.Z=e("./categories/Z/regex")},{"./categories/Cc/regex":61,"./categories/Cf/regex":62,"./categories/P/regex":63,"./categories/Z/regex":64,"./properties/Any/regex":66}],66:[function(e,r,t){r.exports=/[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/},{}],67:[function(e,r,t){"use strict";r.exports=e("./lib/")},{"./lib/":9}]},{},[67])(67)}); diff --git a/src/utils/marked b/src/utils/marked deleted file mode 160000 index 38f1727f..00000000 --- a/src/utils/marked +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 38f1727ffee0820975677027b8968bc1954e6637 diff --git a/src/utils/mermaid/mermaid.css b/src/utils/mermaid/mermaid.css deleted file mode 100644 index 769933f0..00000000 --- a/src/utils/mermaid/mermaid.css +++ /dev/null @@ -1,273 +0,0 @@ -/* Flowchart variables */ -/* Sequence Diagram variables */ -/* Gantt chart variables */ -.mermaid .label { - color: #333; -} -.node rect, -.node circle, -.node ellipse, -.node polygon { - fill: #ECECFF; - stroke: #CCCCFF; - stroke-width: 1px; -} -.edgePath .path { - stroke: #333333; -} -.edgeLabel { - background-color: #e8e8e8; -} -.cluster rect { - fill: #ffffde !important; - rx: 4 !important; - stroke: #aaaa33 !important; - stroke-width: 1px !important; -} -.cluster text { - fill: #333; -} -.actor { - stroke: #CCCCFF; - fill: #ECECFF; -} -text.actor { - fill: black; - stroke: none; -} -.actor-line { - stroke: grey; -} -.messageLine0 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: #333; -} -.messageLine1 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - stroke: #333; -} -#arrowhead { - fill: #333; -} -#crosshead path { - fill: #333 !important; - stroke: #333 !important; -} -.messageText { - fill: #333; - stroke: none; -} -.labelBox { - stroke: #CCCCFF; - fill: #ECECFF; -} -.labelText { - fill: black; - stroke: none; -} -.loopText { - fill: black; - stroke: none; -} -.loopLine { - stroke-width: 2; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: #CCCCFF; -} -.note { - stroke: #aaaa33; - fill: #fff5ad; -} -.noteText { - fill: black; - stroke: none; - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} -/** Section styling */ -.section { - stroke: none; - opacity: 0.2; -} -.section0 { - fill: rgba(102, 102, 255, 0.49); -} -.section2 { - fill: #fff400; -} -.section1, -.section3 { - fill: white; - opacity: 0.2; -} -.sectionTitle0 { - fill: #333; -} -.sectionTitle1 { - fill: #333; -} -.sectionTitle2 { - fill: #333; -} -.sectionTitle3 { - fill: #333; -} -.sectionTitle { - text-anchor: start; - font-size: 11px; - text-height: 14px; -} -/* Grid and axis */ -.grid .tick { - stroke: lightgrey; - opacity: 0.3; - shape-rendering: crispEdges; -} -.grid path { - stroke-width: 0; -} -/* Today line */ -.today { - fill: none; - stroke: red; - stroke-width: 2px; -} -/* Task styling */ -/* Default task */ -.task { - stroke-width: 2; -} -.taskText { - text-anchor: middle; - font-size: 11px; -} -.taskTextOutsideRight { - fill: black; - text-anchor: start; - font-size: 11px; -} -.taskTextOutsideLeft { - fill: black; - text-anchor: end; - font-size: 11px; -} -/* Specific task settings for the sections*/ -.taskText0, -.taskText1, -.taskText2, -.taskText3 { - fill: white; -} -.task0, -.task1, -.task2, -.task3 { - fill: #8a90dd; - stroke: #534fbc; -} -.taskTextOutside0, -.taskTextOutside2 { - fill: black; -} -.taskTextOutside1, -.taskTextOutside3 { - fill: black; -} -/* Active task */ -.active0, -.active1, -.active2, -.active3 { - fill: #bfc7ff; - stroke: #534fbc; -} -.activeText0, -.activeText1, -.activeText2, -.activeText3 { - fill: black !important; -} -/* Completed task */ -.done0, -.done1, -.done2, -.done3 { - stroke: grey; - fill: lightgrey; - stroke-width: 2; -} -.doneText0, -.doneText1, -.doneText2, -.doneText3 { - fill: black !important; -} -/* Tasks on the critical line */ -.crit0, -.crit1, -.crit2, -.crit3 { - stroke: #ff8888; - fill: red; - stroke-width: 2; -} -.activeCrit0, -.activeCrit1, -.activeCrit2, -.activeCrit3 { - stroke: #ff8888; - fill: #bfc7ff; - stroke-width: 2; -} -.doneCrit0, -.doneCrit1, -.doneCrit2, -.doneCrit3 { - stroke: #ff8888; - fill: lightgrey; - stroke-width: 2; - cursor: pointer; - shape-rendering: crispEdges; -} -.doneCritText0, -.doneCritText1, -.doneCritText2, -.doneCritText3 { - fill: black !important; -} -.activeCritText0, -.activeCritText1, -.activeCritText2, -.activeCritText3 { - fill: black !important; -} -.titleText { - text-anchor: middle; - font-size: 18px; - fill: black; -} -/* - - -*/ -.node text { - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} -div.mermaidTooltip { - position: absolute; - text-align: center; - max-width: 200px; - padding: 2px; - font-family: 'trebuchet ms', verdana, arial; - font-size: 12px; - background: #ffffde; - border: 1px solid #aaaa33; - border-radius: 2px; - pointer-events: none; - z-index: 100; -} diff --git a/src/utils/mermaid/mermaid.dark.css b/src/utils/mermaid/mermaid.dark.css deleted file mode 100644 index df49a4e1..00000000 --- a/src/utils/mermaid/mermaid.dark.css +++ /dev/null @@ -1,275 +0,0 @@ -/* Flowchart variables */ -/* Sequence Diagram variables */ -/* Gantt chart variables */ -.mermaid .label { - color: #323D47; -} -.node rect, -.node circle, -.node ellipse, -.node polygon { - fill: #BDD5EA; - stroke: #81B1DB; - stroke-width: 1px; -} -.edgePath .path { - stroke: lightgrey; -} -.edgeLabel { - background-color: #e8e8e8; -} -.cluster rect { - fill: #6D6D65 !important; - rx: 4 !important; - stroke: rgba(255, 255, 255, 0.25) !important; - stroke-width: 1px !important; -} -.cluster text { - fill: #F9FFFE; -} -.actor { - stroke: #81B1DB; - fill: #BDD5EA; -} -text.actor { - fill: black; - stroke: none; -} -.actor-line { - stroke: lightgrey; -} -.messageLine0 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: lightgrey; -} -.messageLine1 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - stroke: lightgrey; -} -#arrowhead { - fill: lightgrey !important; -} -#crosshead path { - fill: lightgrey !important; - stroke: lightgrey !important; -} -.messageText { - fill: lightgrey; - stroke: none; -} -.labelBox { - stroke: #81B1DB; - fill: #BDD5EA; -} -.labelText { - fill: #323D47; - stroke: none; -} -.loopText { - fill: lightgrey; - stroke: none; -} -.loopLine { - stroke-width: 2; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: #81B1DB; -} -.note { - stroke: rgba(255, 255, 255, 0.25); - fill: #fff5ad; -} -.noteText { - fill: black; - stroke: none; - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} -/** Section styling */ -.section { - stroke: none; - opacity: 0.2; -} -.section0 { - fill: rgba(255, 255, 255, 0.3); -} -.section2 { - fill: #EAE8B9; -} -.section1, -.section3 { - fill: white; - opacity: 0.2; -} -.sectionTitle0 { - fill: #F9FFFE; -} -.sectionTitle1 { - fill: #F9FFFE; -} -.sectionTitle2 { - fill: #F9FFFE; -} -.sectionTitle3 { - fill: #F9FFFE; -} -.sectionTitle { - text-anchor: start; - font-size: 11px; - text-height: 14px; -} -/* Grid and axis */ -.grid .tick { - stroke: rgba(255, 255, 255, 0.3); - opacity: 0.3; - shape-rendering: crispEdges; -} -.grid .tick text { - fill: lightgrey; - opacity: 0.5; -} -.grid path { - stroke-width: 0; -} -/* Today line */ -.today { - fill: none; - stroke: #DB5757; - stroke-width: 2px; -} -/* Task styling */ -/* Default task */ -.task { - stroke-width: 1; -} -.taskText { - text-anchor: middle; - font-size: 11px; -} -.taskTextOutsideRight { - fill: #323D47; - text-anchor: start; - font-size: 11px; -} -.taskTextOutsideLeft { - fill: #323D47; - text-anchor: end; - font-size: 11px; -} -/* Specific task settings for the sections*/ -.taskText0, -.taskText1, -.taskText2, -.taskText3 { - fill: #323D47; -} -.task0, -.task1, -.task2, -.task3 { - fill: #BDD5EA; - stroke: rgba(255, 255, 255, 0.5); -} -.taskTextOutside0, -.taskTextOutside2 { - fill: lightgrey; -} -.taskTextOutside1, -.taskTextOutside3 { - fill: lightgrey; -} -/* Active task */ -.active0, -.active1, -.active2, -.active3 { - fill: #81B1DB; - stroke: rgba(255, 255, 255, 0.5); -} -.activeText0, -.activeText1, -.activeText2, -.activeText3 { - fill: #323D47 !important; -} -/* Completed task */ -.done0, -.done1, -.done2, -.done3 { - fill: lightgrey; -} -.doneText0, -.doneText1, -.doneText2, -.doneText3 { - fill: #323D47 !important; -} -/* Tasks on the critical line */ -.crit0, -.crit1, -.crit2, -.crit3 { - stroke: #E83737; - fill: #E83737; - stroke-width: 2; -} -.activeCrit0, -.activeCrit1, -.activeCrit2, -.activeCrit3 { - stroke: #E83737; - fill: #81B1DB; - stroke-width: 2; -} -.doneCrit0, -.doneCrit1, -.doneCrit2, -.doneCrit3 { - stroke: #E83737; - fill: lightgrey; - stroke-width: 1; - cursor: pointer; - shape-rendering: crispEdges; -} -.doneCritText0, -.doneCritText1, -.doneCritText2, -.doneCritText3 { - fill: lightgrey !important; -} -.activeCritText0, -.activeCritText1, -.activeCritText2, -.activeCritText3 { - fill: #323D47 !important; -} -.titleText { - text-anchor: middle; - font-size: 18px; - fill: lightgrey; -} -/* - - -*/ -.node text { - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} -div.mermaidTooltip { - position: absolute; - text-align: center; - max-width: 200px; - padding: 2px; - font-family: 'trebuchet ms', verdana, arial; - font-size: 12px; - background: #6D6D65; - border: 1px solid rgba(255, 255, 255, 0.25); - border-radius: 2px; - pointer-events: none; - z-index: 100; -} diff --git a/src/utils/mermaid/mermaid.forest.css b/src/utils/mermaid/mermaid.forest.css deleted file mode 100644 index ecfbe7fe..00000000 --- a/src/utils/mermaid/mermaid.forest.css +++ /dev/null @@ -1,353 +0,0 @@ -/* Flowchart variables */ -/* Sequence Diagram variables */ -/* Gantt chart variables */ -.mermaid .label { - font-family: 'trebuchet ms', verdana, arial; - color: #333; -} -.node rect, -.node circle, -.node ellipse, -.node polygon { - fill: #cde498; - stroke: #13540c; - stroke-width: 1px; -} -.edgePath .path { - stroke: green; - stroke-width: 1.5px; -} -.edgeLabel { - background-color: #e8e8e8; -} -.cluster rect { - fill: #cdffb2 !important; - rx: 4 !important; - stroke: #6eaa49 !important; - stroke-width: 1px !important; -} -.cluster text { - fill: #333; -} -.actor { - stroke: #13540c; - fill: #cde498; -} -text.actor { - fill: black; - stroke: none; -} -.actor-line { - stroke: grey; -} -.messageLine0 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: #333; -} -.messageLine1 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - stroke: #333; -} -#arrowhead { - fill: #333; -} -#crosshead path { - fill: #333 !important; - stroke: #333 !important; -} -.messageText { - fill: #333; - stroke: none; -} -.labelBox { - stroke: #326932; - fill: #cde498; -} -.labelText { - fill: black; - stroke: none; -} -.loopText { - fill: black; - stroke: none; -} -.loopLine { - stroke-width: 2; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: #326932; -} -.note { - stroke: #6eaa49; - fill: #fff5ad; -} -.noteText { - fill: black; - stroke: none; - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} -/** Section styling */ -.section { - stroke: none; - opacity: 0.2; -} -.section0 { - fill: #6eaa49; -} -.section2 { - fill: #6eaa49; -} -.section1, -.section3 { - fill: white; - opacity: 0.2; -} -.sectionTitle0 { - fill: #333; -} -.sectionTitle1 { - fill: #333; -} -.sectionTitle2 { - fill: #333; -} -.sectionTitle3 { - fill: #333; -} -.sectionTitle { - text-anchor: start; - font-size: 11px; - text-height: 14px; -} -/* Grid and axis */ -.grid .tick { - stroke: lightgrey; - opacity: 0.3; - shape-rendering: crispEdges; -} -.grid path { - stroke-width: 0; -} -/* Today line */ -.today { - fill: none; - stroke: red; - stroke-width: 2px; -} -/* Task styling */ -/* Default task */ -.task { - stroke-width: 2; -} -.taskText { - text-anchor: middle; - font-size: 11px; -} -.taskTextOutsideRight { - fill: black; - text-anchor: start; - font-size: 11px; -} -.taskTextOutsideLeft { - fill: black; - text-anchor: end; - font-size: 11px; -} -/* Specific task settings for the sections*/ -.taskText0, -.taskText1, -.taskText2, -.taskText3 { - fill: white; -} -.task0, -.task1, -.task2, -.task3 { - fill: #487e3a; - stroke: #13540c; -} -.taskTextOutside0, -.taskTextOutside2 { - fill: black; -} -.taskTextOutside1, -.taskTextOutside3 { - fill: black; -} -/* Active task */ -.active0, -.active1, -.active2, -.active3 { - fill: #cde498; - stroke: #13540c; -} -.activeText0, -.activeText1, -.activeText2, -.activeText3 { - fill: black !important; -} -/* Completed task */ -.done0, -.done1, -.done2, -.done3 { - stroke: grey; - fill: lightgrey; - stroke-width: 2; -} -.doneText0, -.doneText1, -.doneText2, -.doneText3 { - fill: black !important; -} -/* Tasks on the critical line */ -.crit0, -.crit1, -.crit2, -.crit3 { - stroke: #ff8888; - fill: red; - stroke-width: 2; -} -.activeCrit0, -.activeCrit1, -.activeCrit2, -.activeCrit3 { - stroke: #ff8888; - fill: #cde498; - stroke-width: 2; -} -.doneCrit0, -.doneCrit1, -.doneCrit2, -.doneCrit3 { - stroke: #ff8888; - fill: lightgrey; - stroke-width: 2; - cursor: pointer; - shape-rendering: crispEdges; -} -.doneCritText0, -.doneCritText1, -.doneCritText2, -.doneCritText3 { - fill: black !important; -} -.activeCritText0, -.activeCritText1, -.activeCritText2, -.activeCritText3 { - fill: black !important; -} -.titleText { - text-anchor: middle; - font-size: 18px; - fill: black; -} -/* - - -*/ -g.classGroup text { - fill: #13540c; - stroke: none; - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} -g.classGroup rect { - fill: #cde498; - stroke: #13540c; -} -g.classGroup line { - stroke: #13540c; - stroke-width: 1; -} -svg .classLabel .box { - stroke: none; - stroke-width: 0; - fill: #cde498; - opacity: 0.5; -} -svg .classLabel .label { - fill: #13540c; -} -.relation { - stroke: #13540c; - stroke-width: 1; - fill: none; -} -.composition { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} -#compositionStart { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} -#compositionEnd { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} -.aggregation { - fill: #cde498; - stroke: #13540c; - stroke-width: 1; -} -#aggregationStart { - fill: #cde498; - stroke: #13540c; - stroke-width: 1; -} -#aggregationEnd { - fill: #cde498; - stroke: #13540c; - stroke-width: 1; -} -#dependencyStart { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} -#dependencyEnd { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} -#extensionStart { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} -#extensionEnd { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} -.node text { - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} -div.mermaidTooltip { - position: absolute; - text-align: center; - max-width: 200px; - padding: 2px; - font-family: 'trebuchet ms', verdana, arial; - font-size: 12px; - background: #cdffb2; - border: 1px solid #6eaa49; - border-radius: 2px; - pointer-events: none; - z-index: 100; -} diff --git a/src/utils/mermaid/mermaidAPI.min.js b/src/utils/mermaid/mermaidAPI.min.js deleted file mode 100644 index 8a02df62..00000000 --- a/src/utils/mermaid/mermaidAPI.min.js +++ /dev/null @@ -1,22 +0,0 @@ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n;"undefined"!=typeof window?n=window:"undefined"!=typeof global?n=global:"undefined"!=typeof self&&(n=self),n.mermaidAPI=t()}}(function(){var define,module,exports;return function t(n,e,r){function i(u,o){if(!e[u]){if(!n[u]){var s="function"==typeof require&&require;if(!o&&s)return s(u,!0);if(a)return a(u,!0);var c=new Error("Cannot find module '"+u+"'");throw c.code="MODULE_NOT_FOUND",c}var l=e[u]={exports:{}};n[u][0].call(l.exports,function(t){var e=n[u][1][t];return i(e?e:t)},l,l.exports,t,n,e,r)}return e[u].exports}for(var a="function"==typeof require&&require,u=0;ut?-1:t>n?1:t>=n?0:0/0}function i(t){return null===t?0/0:+t}function a(t){return!isNaN(t)}function u(t){return{left:function(n,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=n.length);i>r;){var a=r+i>>>1;t(n[a],e)<0?r=a+1:i=a}return r},right:function(n,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=n.length);i>r;){var a=r+i>>>1;t(n[a],e)>0?i=a:r=a+1}return r}}}function o(t){return t.length}function s(t){for(var n=1;t*n%1;)n*=10;return n}function c(t,n){for(var e in n)Object.defineProperty(t.prototype,e,{value:n[e],enumerable:!1})}function l(){this._=Object.create(null)}function h(t){return(t+="")===gu||t[0]===yu?yu+t:t}function f(t){return(t+="")[0]===yu?t.slice(1):t}function d(t){return h(t)in this._}function p(t){return(t=h(t))in this._&&delete this._[t]}function g(){var t=[];for(var n in this._)t.push(f(n));return t}function y(){var t=0;for(var n in this._)++t;return t}function m(){for(var t in this._)return!1;return!0}function v(){this._=Object.create(null)}function _(t){return t}function b(t,n,e){return function(){var r=e.apply(n,arguments);return r===n?t:r}}function x(t,n){if(n in t)return n;n=n.charAt(0).toUpperCase()+n.slice(1);for(var e=0,r=mu.length;r>e;++e){var i=mu[e]+n;if(i in t)return i}}function w(){}function A(){}function k(t){function n(){for(var n,r=e,i=-1,a=r.length;++ie;e++)for(var i,a=t[e],u=0,o=a.length;o>u;u++)(i=a[u])&&n(i,u,e);return t}function q(t){return _u(t,Eu),t}function G(t){var n,e;return function(r,i,a){var u,o=t[a].update,s=o.length;for(a!=e&&(e=a,n=0),i>=n&&(n=i+1);!(u=o[n])&&++n0&&(t=t.slice(0,o));var c=Mu.get(t);return c&&(t=c,s=Z),o?n?i:r:n?w:a}function V(t,n){return function(e){var r=eu.event;eu.event=e,n[0]=this.__data__;try{t.apply(this,n)}finally{eu.event=r}}}function Z(t,n){var e=V(t,n);return function(t){var n=this,r=t.relatedTarget;r&&(r===n||8&r.compareDocumentPosition(n))||e.call(n,t)}}function X(n){var r=".dragsuppress-"+ ++Du,i="click"+r,a=eu.select(e(n)).on("touchmove"+r,E).on("dragstart"+r,E).on("selectstart"+r,E);if(null==Su&&(Su="onselectstart"in n?!1:x(n.style,"userSelect")),Su){var u=t(n).style,o=u[Su];u[Su]="none"}return function(t){if(a.on(r,null),Su&&(u[Su]=o),t){var n=function(){a.on(i,null)};a.on(i,function(){E(),n()},!0),setTimeout(n,0)}}}function K(t,n){n.changedTouches&&(n=n.changedTouches[0]);var r=t.ownerSVGElement||t;if(r.createSVGPoint){var i=r.createSVGPoint();if(0>Cu){var a=e(t);if(a.scrollX||a.scrollY){r=eu.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=r[0][0].getScreenCTM();Cu=!(u.f||u.e),r.remove()}}return Cu?(i.x=n.pageX,i.y=n.pageY):(i.x=n.clientX,i.y=n.clientY),i=i.matrixTransform(t.getScreenCTM().inverse()),[i.x,i.y]}var o=t.getBoundingClientRect();return[n.clientX-o.left-t.clientLeft,n.clientY-o.top-t.clientTop]}function Q(){return eu.event.changedTouches[0].identifier}function J(t){return t>0?1:0>t?-1:0}function tt(t,n,e){return(n[0]-t[0])*(e[1]-t[1])-(n[1]-t[1])*(e[0]-t[0])}function nt(t){return t>1?0:-1>t?Ou:Math.acos(t)}function et(t){return t>1?Bu:-1>t?-Bu:Math.asin(t)}function rt(t){return((t=Math.exp(t))-1/t)/2}function it(t){return((t=Math.exp(t))+1/t)/2}function at(t){return((t=Math.exp(2*t))-1)/(t+1)}function ut(t){return(t=Math.sin(t/2))*t}function ot(){}function st(t,n,e){return this instanceof st?(this.h=+t,this.s=+n,void(this.l=+e)):arguments.length<2?t instanceof st?new st(t.h,t.s,t.l):wt(""+t,At,st):new st(t,n,e)}function ct(t,n,e){function r(t){return t>360?t-=360:0>t&&(t+=360),60>t?a+(u-a)*t/60:180>t?u:240>t?a+(u-a)*(240-t)/60:a}function i(t){return Math.round(255*r(t))}var a,u;return t=isNaN(t)?0:(t%=360)<0?t+360:t,n=isNaN(n)?0:0>n?0:n>1?1:n,e=0>e?0:e>1?1:e,u=.5>=e?e*(1+n):e+n-e*n,a=2*e-u,new vt(i(t+120),i(t),i(t-120))}function lt(t,n,e){return this instanceof lt?(this.h=+t,this.c=+n,void(this.l=+e)):arguments.length<2?t instanceof lt?new lt(t.h,t.c,t.l):t instanceof ft?pt(t.l,t.a,t.b):pt((t=kt((t=eu.rgb(t)).r,t.g,t.b)).l,t.a,t.b):new lt(t,n,e)}function ht(t,n,e){return isNaN(t)&&(t=0),isNaN(n)&&(n=0),new ft(e,Math.cos(t*=Nu)*n,Math.sin(t)*n)}function ft(t,n,e){return this instanceof ft?(this.l=+t,this.a=+n,void(this.b=+e)):arguments.length<2?t instanceof ft?new ft(t.l,t.a,t.b):t instanceof lt?ht(t.h,t.c,t.l):kt((t=vt(t)).r,t.g,t.b):new ft(t,n,e)}function dt(t,n,e){var r=(t+16)/116,i=r+n/500,a=r-e/200;return i=gt(i)*Hu,r=gt(r)*Vu,a=gt(a)*Zu,new vt(mt(3.2404542*i-1.5371385*r-.4985314*a),mt(-.969266*i+1.8760108*r+.041556*a),mt(.0556434*i-.2040259*r+1.0572252*a))}function pt(t,n,e){return t>0?new lt(Math.atan2(e,n)*Pu,Math.sqrt(n*n+e*e),t):new lt(0/0,0/0,t)}function gt(t){return t>.206893034?t*t*t:(t-4/29)/7.787037}function yt(t){return t>.008856?Math.pow(t,1/3):7.787037*t+4/29}function mt(t){return Math.round(255*(.00304>=t?12.92*t:1.055*Math.pow(t,1/2.4)-.055))}function vt(t,n,e){return this instanceof vt?(this.r=~~t,this.g=~~n,void(this.b=~~e)):arguments.length<2?t instanceof vt?new vt(t.r,t.g,t.b):wt(""+t,vt,ct):new vt(t,n,e)}function _t(t){return new vt(t>>16,t>>8&255,255&t)}function bt(t){return _t(t)+""}function xt(t){return 16>t?"0"+Math.max(0,t).toString(16):Math.min(255,t).toString(16)}function wt(t,n,e){t=t.toLowerCase();var r,i,a,u=0,o=0,s=0;if(r=/([a-z]+)\((.*)\)/.exec(t))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return n(Mt(i[0]),Mt(i[1]),Mt(i[2]))}return(a=Qu.get(t))?n(a.r,a.g,a.b):(null==t||"#"!==t.charAt(0)||isNaN(a=parseInt(t.slice(1),16))||(4===t.length?(u=(3840&a)>>4,u=u>>4|u,o=240&a,o=o>>4|o,s=15&a,s=s<<4|s):7===t.length&&(u=(16711680&a)>>16,o=(65280&a)>>8,s=255&a)),n(u,o,s))}function At(t,n,e){var r,i,a=Math.min(t/=255,n/=255,e/=255),u=Math.max(t,n,e),o=u-a,s=(u+a)/2;return o?(i=.5>s?o/(u+a):o/(2-u-a),r=t==u?(n-e)/o+(e>n?6:0):n==u?(e-t)/o+2:(t-n)/o+4,r*=60):(r=0/0,i=s>0&&1>s?0:r),new st(r,i,s)}function kt(t,n,e){t=Et(t),n=Et(n),e=Et(e);var r=yt((.4124564*t+.3575761*n+.1804375*e)/Hu),i=yt((.2126729*t+.7151522*n+.072175*e)/Vu),a=yt((.0193339*t+.119192*n+.9503041*e)/Zu);return ft(116*i-16,500*(r-i),200*(i-a))}function Et(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function Mt(t){var n=parseFloat(t);return"%"===t.charAt(t.length-1)?Math.round(2.55*n):n}function St(t){return"function"==typeof t?t:function(){return t}}function Dt(t){return function(n,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Ct(n,e,t,r)}}function Ct(t,n,e,r){function i(){var t,n=s.status;if(!n&&Ft(s)||n>=200&&300>n||304===n){try{t=e.call(a,s)}catch(r){return void u.error.call(a,r)}u.load.call(a,t)}else u.error.call(a,s)}var a={},u=eu.dispatch("beforesend","progress","load","error"),o={},s=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in s||!/^(http(s)?:)?\/\//.test(t)||(s=new XDomainRequest),"onload"in s?s.onload=s.onerror=i:s.onreadystatechange=function(){s.readyState>3&&i()},s.onprogress=function(t){var n=eu.event;eu.event=t;try{u.progress.call(a,s)}finally{eu.event=n}},a.header=function(t,n){return t=(t+"").toLowerCase(),arguments.length<2?o[t]:(null==n?delete o[t]:o[t]=n+"",a)},a.mimeType=function(t){return arguments.length?(n=null==t?null:t+"",a):n},a.responseType=function(t){return arguments.length?(c=t,a):c},a.response=function(t){return e=t,a},["get","post"].forEach(function(t){a[t]=function(){return a.send.apply(a,[t].concat(iu(arguments)))}}),a.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),s.open(e,t,!0),null==n||"accept"in o||(o.accept=n+",*/*"),s.setRequestHeader)for(var l in o)s.setRequestHeader(l,o[l]);return null!=n&&s.overrideMimeType&&s.overrideMimeType(n),null!=c&&(s.responseType=c),null!=i&&a.on("error",i).on("load",function(t){i(null,t)}),u.beforesend.call(a,s),s.send(null==r?null:r),a},a.abort=function(){return s.abort(),a},eu.rebind(a,u,"on"),null==r?a:a.get(Tt(r))}function Tt(t){return 1===t.length?function(n,e){t(null==n?e:null)}:t}function Ft(t){var n=t.responseType;return n&&"text"!==n?t.response:t.responseText}function Ot(){var t=Lt(),n=It()-t;n>24?(isFinite(n)&&(clearTimeout(eo),eo=setTimeout(Ot,n)),no=0):(no=1,io(Ot))}function Lt(){var t=Date.now();for(ro=Ju;ro;)t>=ro.t&&(ro.f=ro.c(t-ro.t)),ro=ro.n;return t}function It(){for(var t,n=Ju,e=1/0;n;)n.f?n=t?t.n=n.n:Ju=n.n:(n.t8?function(t){return t/e}:function(t){return t*e},symbol:t}}function Pt(t){var n=t.decimal,e=t.thousands,r=t.grouping,i=t.currency,a=r&&e?function(t,n){for(var i=t.length,a=[],u=0,o=r[0],s=0;i>0&&o>0&&(s+o+1>n&&(o=Math.max(1,n-s)),a.push(t.substring(i-=o,i+o)),!((s+=o+1)>n));)o=r[u=(u+1)%r.length];return a.reverse().join(e)}:_;return function(t){var e=uo.exec(t),r=e[1]||" ",u=e[2]||">",o=e[3]||"-",s=e[4]||"",c=e[5],l=+e[6],h=e[7],f=e[8],d=e[9],p=1,g="",y="",m=!1,v=!0;switch(f&&(f=+f.substring(1)),(c||"0"===r&&"="===u)&&(c=r="0",u="="),d){case"n":h=!0,d="g";break;case"%":p=100,y="%",d="f";break;case"p":p=100,y="%",d="r";break;case"b":case"o":case"x":case"X":"#"===s&&(g="0"+d.toLowerCase());case"c":v=!1;case"d":m=!0,f=0;break;case"s":p=-1,d="r"}"$"===s&&(g=i[0],y=i[1]),"r"!=d||f||(d="g"),null!=f&&("g"==d?f=Math.max(1,Math.min(21,f)):("e"==d||"f"==d)&&(f=Math.max(0,Math.min(20,f)))),d=oo.get(d)||Rt;var _=c&&h;return function(t){var e=y;if(m&&t%1)return"";var i=0>t||0===t&&0>1/t?(t=-t,"-"):"-"===o?"":o;if(0>p){var s=eu.formatPrefix(t,f);t=s.scale(t),e=s.symbol+y}else t*=p;t=d(t,f);var b,x,w=t.lastIndexOf(".");if(0>w){var A=v?t.lastIndexOf("e"):-1;0>A?(b=t,x=""):(b=t.substring(0,A),x=t.substring(A))}else b=t.substring(0,w),x=n+t.substring(w+1);!c&&h&&(b=a(b,1/0));var k=g.length+b.length+x.length+(_?0:i.length),E=l>k?new Array(k=l-k+1).join(r):"";return _&&(b=a(E+b,E.length?l-x.length:1/0)),i+=g,t=b+x,("<"===u?i+t+E:">"===u?E+i+t:"^"===u?E.substring(0,k>>=1)+i+t+E.substring(k):i+(_?t:E+t))+e}}}function Rt(t){return t+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Yt(t,n,e){function r(n){var e=t(n),r=a(e,1);return r-n>n-e?e:r}function i(e){return n(e=t(new co(e-1)),1),e}function a(t,e){return n(t=new co(+t),e),t}function u(t,r,a){var u=i(t),o=[];if(a>1)for(;r>u;)e(u)%a||o.push(new Date(+u)),n(u,1);else for(;r>u;)o.push(new Date(+u)),n(u,1);return o}function o(t,n,e){try{co=jt;var r=new jt;return r._=t,u(r,n,e)}finally{co=Date}}t.floor=t,t.round=r,t.ceil=i,t.offset=a,t.range=u;var s=t.utc=Ut(t);return s.floor=s,s.round=Ut(r),s.ceil=Ut(i),s.offset=Ut(a),s.range=o,t}function Ut(t){return function(n,e){try{co=jt;var r=new jt;return r._=n,t(r,e)._}finally{co=Date}}}function $t(t){function n(t){function n(n){for(var e,i,a,u=[],o=-1,s=0;++oo;){if(r>=c)return-1;if(i=n.charCodeAt(o++),37===i){if(u=n.charAt(o++),a=C[u in ho?n.charAt(o++):u],!a||(r=a(t,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function r(t,n,e){w.lastIndex=0;var r=w.exec(n.slice(e));return r?(t.w=A.get(r[0].toLowerCase()),e+r[0].length):-1}function i(t,n,e){b.lastIndex=0;var r=b.exec(n.slice(e));return r?(t.w=x.get(r[0].toLowerCase()),e+r[0].length):-1}function a(t,n,e){M.lastIndex=0;var r=M.exec(n.slice(e));return r?(t.m=S.get(r[0].toLowerCase()),e+r[0].length):-1}function u(t,n,e){k.lastIndex=0;var r=k.exec(n.slice(e));return r?(t.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function o(t,n,r){return e(t,D.c.toString(),n,r)}function s(t,n,r){return e(t,D.x.toString(),n,r)}function c(t,n,r){return e(t,D.X.toString(),n,r)}function l(t,n,e){var r=_.get(n.slice(e,e+=2).toLowerCase());return null==r?-1:(t.p=r,e)}var h=t.dateTime,f=t.date,d=t.time,p=t.periods,g=t.days,y=t.shortDays,m=t.months,v=t.shortMonths;n.utc=function(t){function e(t){try{co=jt;var n=new co;return n._=t,r(n)}finally{co=Date}}var r=n(t);return e.parse=function(t){try{co=jt;var n=r.parse(t);return n&&n._}finally{co=Date}},e.toString=r.toString,e},n.multi=n.utc.multi=cn;var _=eu.map(),b=zt(g),x=qt(g),w=zt(y),A=qt(y),k=zt(m),E=qt(m),M=zt(v),S=qt(v);p.forEach(function(t,n){_.set(t.toLowerCase(),n)});var D={a:function(t){return y[t.getDay()]},A:function(t){return g[t.getDay()]},b:function(t){return v[t.getMonth()]},B:function(t){return m[t.getMonth()]},c:n(h),d:function(t,n){return Wt(t.getDate(),n,2)},e:function(t,n){return Wt(t.getDate(),n,2)},H:function(t,n){return Wt(t.getHours(),n,2)},I:function(t,n){return Wt(t.getHours()%12||12,n,2)},j:function(t,n){return Wt(1+so.dayOfYear(t),n,3)},L:function(t,n){return Wt(t.getMilliseconds(),n,3)},m:function(t,n){return Wt(t.getMonth()+1,n,2)},M:function(t,n){return Wt(t.getMinutes(),n,2)},p:function(t){return p[+(t.getHours()>=12)]},S:function(t,n){return Wt(t.getSeconds(),n,2)},U:function(t,n){return Wt(so.sundayOfYear(t),n,2)},w:function(t){return t.getDay()},W:function(t,n){return Wt(so.mondayOfYear(t),n,2)},x:n(f),X:n(d),y:function(t,n){return Wt(t.getFullYear()%100,n,2)},Y:function(t,n){return Wt(t.getFullYear()%1e4,n,4)},Z:on,"%":function(){return"%"}},C={a:r,A:i,b:a,B:u,c:o,d:tn,e:tn,H:en,I:en,j:nn,L:un,m:Jt,M:rn,p:l,S:an,U:Ht,w:Gt,W:Vt,x:s,X:c,y:Xt,Y:Zt,Z:Kt,"%":sn};return n}function Wt(t,n,e){var r=0>t?"-":"",i=(r?-t:t)+"",a=i.length;return r+(e>a?new Array(e-a+1).join(n)+i:i)}function zt(t){return new RegExp("^(?:"+t.map(eu.requote).join("|")+")","i")}function qt(t){for(var n=new l,e=-1,r=t.length;++e68?1900:2e3)}function Jt(t,n,e){fo.lastIndex=0;var r=fo.exec(n.slice(e,e+2));return r?(t.m=r[0]-1,e+r[0].length):-1}function tn(t,n,e){fo.lastIndex=0;var r=fo.exec(n.slice(e,e+2));return r?(t.d=+r[0],e+r[0].length):-1}function nn(t,n,e){fo.lastIndex=0;var r=fo.exec(n.slice(e,e+3));return r?(t.j=+r[0],e+r[0].length):-1}function en(t,n,e){fo.lastIndex=0;var r=fo.exec(n.slice(e,e+2));return r?(t.H=+r[0],e+r[0].length):-1}function rn(t,n,e){fo.lastIndex=0;var r=fo.exec(n.slice(e,e+2));return r?(t.M=+r[0],e+r[0].length):-1}function an(t,n,e){fo.lastIndex=0;var r=fo.exec(n.slice(e,e+2));return r?(t.S=+r[0],e+r[0].length):-1}function un(t,n,e){fo.lastIndex=0;var r=fo.exec(n.slice(e,e+3));return r?(t.L=+r[0],e+r[0].length):-1}function on(t){var n=t.getTimezoneOffset(),e=n>0?"-":"+",r=pu(n)/60|0,i=pu(n)%60;return e+Wt(r,"0",2)+Wt(i,"0",2)}function sn(t,n,e){po.lastIndex=0;var r=po.exec(n.slice(e,e+1));return r?e+r[0].length:-1}function cn(t){for(var n=t.length,e=-1;++e=0?1:-1,o=u*e,s=Math.cos(n),c=Math.sin(n),l=a*c,h=i*s+l*Math.cos(o),f=l*u*Math.sin(o);bo.add(Math.atan2(f,h)),r=t,i=s,a=c}var n,e,r,i,a;xo.point=function(u,o){xo.point=t,r=(n=u)*Nu,i=Math.cos(o=(e=o)*Nu/2+Ou/4),a=Math.sin(o)},xo.lineEnd=function(){t(n,e)}}function yn(t){var n=t[0],e=t[1],r=Math.cos(e);return[r*Math.cos(n),r*Math.sin(n),Math.sin(e)]}function mn(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]}function vn(t,n){return[t[1]*n[2]-t[2]*n[1],t[2]*n[0]-t[0]*n[2],t[0]*n[1]-t[1]*n[0]]}function _n(t,n){t[0]+=n[0],t[1]+=n[1],t[2]+=n[2]}function bn(t,n){return[t[0]*n,t[1]*n,t[2]*n]}function xn(t){var n=Math.sqrt(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=n,t[1]/=n,t[2]/=n}function wn(t){return[Math.atan2(t[1],t[0]),et(t[2])]}function An(t,n){return pu(t[0]-n[0])o;++o)i.point((e=t[o])[0],e[1]);return void i.lineEnd()}var s=new Ln(e,t,null,!0),c=new Ln(e,null,s,!1);s.o=c,a.push(s),u.push(c),s=new Ln(r,t,null,!1),c=new Ln(r,null,s,!0),s.o=c,a.push(s),u.push(c)}}),u.sort(n),On(a),On(u),a.length){for(var o=0,s=e,c=u.length;c>o;++o)u[o].e=s=!s;for(var l,h,f=a[0];;){for(var d=f,p=!0;d.v;)if((d=d.n)===f)return;l=d.z,i.lineStart();do{if(d.v=d.o.v=!0,d.e){if(p)for(var o=0,c=l.length;c>o;++o)i.point((h=l[o])[0],h[1]);else r(d.x,d.n.x,1,i);d=d.n}else{if(p){l=d.p.z;for(var o=l.length-1;o>=0;--o)i.point((h=l[o])[0],h[1])}else r(d.x,d.p.x,-1,i);d=d.p}d=d.o,l=d.z,p=!p}while(!d.v);i.lineEnd()}}}function On(t){if(n=t.length){for(var n,e,r=0,i=t[0];++r0){for(x||(a.polygonStart(),x=!0),a.lineStart();++u1&&2&n&&e.push(e.pop().concat(e.shift())),d.push(e.filter(Bn))}var d,p,g,y=n(a),m=i.invert(r[0],r[1]),v={point:u,lineStart:s,lineEnd:c,polygonStart:function(){v.point=l,v.lineStart=h,v.lineEnd=f,d=[],p=[]},polygonEnd:function(){v.point=u,v.lineStart=s,v.lineEnd=c,d=eu.merge(d);var t=Un(m,p);d.length?(x||(a.polygonStart(),x=!0),Fn(d,Pn,t,e,a)):t&&(x||(a.polygonStart(),x=!0),a.lineStart(),e(null,null,1,a),a.lineEnd()),x&&(a.polygonEnd(),x=!1),d=p=null},sphere:function(){a.polygonStart(),a.lineStart(),e(null,null,1,a),a.lineEnd(),a.polygonEnd()}},_=Nn(),b=n(_),x=!1;return v}}function Bn(t){return t.length>1}function Nn(){var t,n=[];return{lineStart:function(){n.push(t=[])},point:function(n,e){t.push([n,e])},lineEnd:w,buffer:function(){var e=n;return n=[],t=null,e},rejoin:function(){n.length>1&&n.push(n.pop().concat(n.shift()))}}}function Pn(t,n){return((t=t.x)[0]<0?t[1]-Bu-Tu:Bu-t[1])-((n=n.x)[0]<0?n[1]-Bu-Tu:Bu-n[1])}function Rn(t){var n,e=0/0,r=0/0,i=0/0;return{lineStart:function(){t.lineStart(),n=1},point:function(a,u){var o=a>0?Ou:-Ou,s=pu(a-e);pu(s-Ou)0?Bu:-Bu),t.point(i,r),t.lineEnd(),t.lineStart(),t.point(o,r),t.point(a,r),n=0):i!==o&&s>=Ou&&(pu(e-i)Tu?Math.atan((Math.sin(n)*(a=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(n))*Math.sin(t))/(i*a*u)):(n+r)/2}function Yn(t,n,e,r){var i;if(null==t)i=e*Bu,r.point(-Ou,i),r.point(0,i),r.point(Ou,i),r.point(Ou,0),r.point(Ou,-i),r.point(0,-i),r.point(-Ou,-i),r.point(-Ou,0),r.point(-Ou,i);else if(pu(t[0]-n[0])>Tu){var a=t[0]o;++o){var c=n[o],l=c.length;if(l)for(var h=c[0],f=h[0],d=h[1]/2+Ou/4,p=Math.sin(d),g=Math.cos(d),y=1;;){y===l&&(y=0),t=c[y];var m=t[0],v=t[1]/2+Ou/4,_=Math.sin(v),b=Math.cos(v),x=m-f,w=x>=0?1:-1,A=w*x,k=A>Ou,E=p*_;if(bo.add(Math.atan2(E*w*Math.sin(A),g*b+E*Math.cos(A))),a+=k?x+w*Lu:x,k^f>=e^m>=e){var M=vn(yn(h),yn(t));xn(M);var S=vn(i,M);xn(S);var D=(k^x>=0?-1:1)*et(S[2]);(r>D||r===D&&(M[0]||M[1]))&&(u+=k^x>=0?1:-1)}if(!y++)break;f=m,p=_,g=b,h=t}}return(-Tu>a||Tu>a&&0>bo)^1&u}function $n(t){function n(t,n){return Math.cos(t)*Math.cos(n)>a}function e(t){var e,a,s,c,l;return{lineStart:function(){c=s=!1,l=1},point:function(h,f){var d,p=[h,f],g=n(h,f),y=u?g?0:i(h,f):g?i(h+(0>h?Ou:-Ou),f):0;if(!e&&(c=s=g)&&t.lineStart(),g!==s&&(d=r(e,p),(An(e,d)||An(p,d))&&(p[0]+=Tu,p[1]+=Tu,g=n(p[0],p[1]))),g!==s)l=0,g?(t.lineStart(),d=r(p,e),t.point(d[0],d[1])):(d=r(e,p),t.point(d[0],d[1]),t.lineEnd()),e=d;else if(o&&e&&u^g){var m;y&a||!(m=r(p,e,!0))||(l=0,u?(t.lineStart(),t.point(m[0][0],m[0][1]),t.point(m[1][0],m[1][1]),t.lineEnd()):(t.point(m[1][0],m[1][1]),t.lineEnd(),t.lineStart(),t.point(m[0][0],m[0][1])))}!g||e&&An(e,p)||t.point(p[0],p[1]),e=p,s=g,a=y},lineEnd:function(){s&&t.lineEnd(),e=null},clean:function(){return l|(c&&s)<<1}}}function r(t,n,e){var r=yn(t),i=yn(n),u=[1,0,0],o=vn(r,i),s=mn(o,o),c=o[0],l=s-c*c;if(!l)return!e&&t;var h=a*s/l,f=-a*c/l,d=vn(u,o),p=bn(u,h),g=bn(o,f);_n(p,g);var y=d,m=mn(p,y),v=mn(y,y),_=m*m-v*(mn(p,p)-1);if(!(0>_)){var b=Math.sqrt(_),x=bn(y,(-m-b)/v);if(_n(x,p),x=wn(x),!e)return x;var w,A=t[0],k=n[0],E=t[1],M=n[1];A>k&&(w=A,A=k,k=w);var S=k-A,D=pu(S-Ou)S;if(!D&&E>M&&(w=E,E=M,M=w),C?D?E+M>0^x[1]<(pu(x[0]-A)Ou^(A<=x[0]&&x[0]<=k)){var T=bn(y,(-m+b)/v);return _n(T,p),[x,wn(T)]}}}function i(n,e){var r=u?t:Ou-t,i=0;return-r>n?i|=1:n>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var a=Math.cos(t),u=a>0,o=pu(a)>Tu,s=ge(t,6*Nu);return In(n,e,s,u?[0,-t]:[-Ou,t-Ou])}function Wn(t,n,e,r){return function(i){var a,u=i.a,o=i.b,s=u.x,c=u.y,l=o.x,h=o.y,f=0,d=1,p=l-s,g=h-c;if(a=t-s,p||!(a>0)){if(a/=p,0>p){if(f>a)return;d>a&&(d=a)}else if(p>0){if(a>d)return;a>f&&(f=a)}if(a=e-s,p||!(0>a)){if(a/=p,0>p){if(a>d)return;a>f&&(f=a)}else if(p>0){if(f>a)return;d>a&&(d=a)}if(a=n-c,g||!(a>0)){if(a/=g,0>g){if(f>a)return;d>a&&(d=a)}else if(g>0){if(a>d)return;a>f&&(f=a)}if(a=r-c,g||!(0>a)){if(a/=g,0>g){if(a>d)return;a>f&&(f=a)}else if(g>0){if(f>a)return;d>a&&(d=a)}return f>0&&(i.a={x:s+f*p,y:c+f*g}),1>d&&(i.b={x:s+d*p,y:c+d*g}),i}}}}}}function zn(t,n,e,r){function i(r,i){return pu(r[0]-t)0?0:3:pu(r[0]-e)0?2:1:pu(r[1]-n)0?1:0:i>0?3:2}function a(t,n){return u(t.x,n.x)}function u(t,n){var e=i(t,1),r=i(n,1);return e!==r?e-r:0===e?n[1]-t[1]:1===e?t[0]-n[0]:2===e?t[1]-n[1]:n[0]-t[0]}return function(o){function s(t){for(var n=0,e=y.length,r=t[1],i=0;e>i;++i)for(var a,u=1,o=y[i],s=o.length,c=o[0];s>u;++u)a=o[u],c[1]<=r?a[1]>r&&tt(c,a,t)>0&&++n:a[1]<=r&&tt(c,a,t)<0&&--n,c=a;return 0!==n}function c(a,o,s,c){var l=0,h=0;if(null==a||(l=i(a,s))!==(h=i(o,s))||u(a,o)<0^s>0){do c.point(0===l||3===l?t:e,l>1?r:n);while((l=(l+s+4)%4)!==h)}else c.point(o[0],o[1])}function l(i,a){return i>=t&&e>=i&&a>=n&&r>=a}function h(t,n){l(t,n)&&o.point(t,n)}function f(){C.point=p,y&&y.push(m=[]),k=!0,A=!1,x=w=0/0}function d(){g&&(p(v,_),b&&A&&S.rejoin(),g.push(S.buffer())),C.point=h,A&&o.lineEnd()}function p(t,n){t=Math.max(-Bo,Math.min(Bo,t)),n=Math.max(-Bo,Math.min(Bo,n));var e=l(t,n);if(y&&m.push([t,n]),k)v=t,_=n,b=e,k=!1,e&&(o.lineStart(),o.point(t,n));else if(e&&A)o.point(t,n);else{var r={a:{x:x,y:w},b:{x:t,y:n}};D(r)?(A||(o.lineStart(),o.point(r.a.x,r.a.y)),o.point(r.b.x,r.b.y),e||o.lineEnd(),E=!1):e&&(o.lineStart(),o.point(t,n),E=!1)}x=t,w=n,A=e}var g,y,m,v,_,b,x,w,A,k,E,M=o,S=Nn(),D=Wn(t,n,e,r),C={point:h,lineStart:f,lineEnd:d,polygonStart:function(){o=S,g=[],y=[],E=!0},polygonEnd:function(){o=M,g=eu.merge(g);var n=s([t,r]),e=E&&n,i=g.length;(e||i)&&(o.polygonStart(),e&&(o.lineStart(),c(null,null,1,o),o.lineEnd()),i&&Fn(g,a,n,c,o),o.polygonEnd()),g=y=m=null}};return C}}function qn(t){var n=0,e=Ou/3,r=oe(t),i=r(n,e);return i.parallels=function(t){return arguments.length?r(n=t[0]*Ou/180,e=t[1]*Ou/180):[n/Ou*180,e/Ou*180]},i}function Gn(t,n){function e(t,n){var e=Math.sqrt(a-2*i*Math.sin(n))/i;return[e*Math.sin(t*=i),u-e*Math.cos(t)]}var r=Math.sin(t),i=(r+Math.sin(n))/2,a=1+r*(2*i-r),u=Math.sqrt(a)/i;return e.invert=function(t,n){var e=u-n;return[Math.atan2(t,e)/i,et((a-(t*t+e*e)*i*i)/(2*i))]},e}function Hn(){function t(t,n){Po+=i*t-r*n,r=t,i=n}var n,e,r,i;$o.point=function(a,u){$o.point=t,n=r=a,e=i=u},$o.lineEnd=function(){t(n,e)}}function Vn(t,n){Ro>t&&(Ro=t),t>Yo&&(Yo=t),jo>n&&(jo=n),n>Uo&&(Uo=n)}function Zn(){function t(t,n){u.push("M",t,",",n,a)}function n(t,n){u.push("M",t,",",n),o.point=e}function e(t,n){u.push("L",t,",",n)}function r(){o.point=t}function i(){u.push("Z")}var a=Xn(4.5),u=[],o={point:t,lineStart:function(){o.point=n},lineEnd:r,polygonStart:function(){o.lineEnd=i},polygonEnd:function(){o.lineEnd=r,o.point=t},pointRadius:function(t){return a=Xn(t),o},result:function(){if(u.length){var t=u.join("");return u=[],t}}};return o}function Xn(t){return"m0,"+t+"a"+t+","+t+" 0 1,1 0,"+-2*t+"a"+t+","+t+" 0 1,1 0,"+2*t+"z"}function Kn(t,n){ko+=t,Eo+=n,++Mo}function Qn(){function t(t,r){var i=t-n,a=r-e,u=Math.sqrt(i*i+a*a);So+=u*(n+t)/2,Do+=u*(e+r)/2,Co+=u,Kn(n=t,e=r)}var n,e;zo.point=function(r,i){zo.point=t,Kn(n=r,e=i)}}function Jn(){zo.point=Kn}function te(){function t(t,n){var e=t-r,a=n-i,u=Math.sqrt(e*e+a*a);So+=u*(r+t)/2,Do+=u*(i+n)/2,Co+=u,u=i*t-r*n,To+=u*(r+t),Fo+=u*(i+n),Oo+=3*u,Kn(r=t,i=n)}var n,e,r,i;zo.point=function(a,u){zo.point=t,Kn(n=r=a,e=i=u)},zo.lineEnd=function(){t(n,e)}}function ne(t){function n(n,e){t.moveTo(n+u,e),t.arc(n,e,u,0,Lu)}function e(n,e){t.moveTo(n,e),o.point=r}function r(n,e){t.lineTo(n,e)}function i(){o.point=n}function a(){ -t.closePath()}var u=4.5,o={point:n,lineStart:function(){o.point=e},lineEnd:i,polygonStart:function(){o.lineEnd=a},polygonEnd:function(){o.lineEnd=i,o.point=n},pointRadius:function(t){return u=t,o},result:w};return o}function ee(t){function n(t){return(o?r:e)(t)}function e(n){return ae(n,function(e,r){e=t(e,r),n.point(e[0],e[1])})}function r(n){function e(e,r){e=t(e,r),n.point(e[0],e[1])}function r(){_=0/0,k.point=a,n.lineStart()}function a(e,r){var a=yn([e,r]),u=t(e,r);i(_,b,v,x,w,A,_=u[0],b=u[1],v=e,x=a[0],w=a[1],A=a[2],o,n),n.point(_,b)}function u(){k.point=e,n.lineEnd()}function s(){r(),k.point=c,k.lineEnd=l}function c(t,n){a(h=t,f=n),d=_,p=b,g=x,y=w,m=A,k.point=a}function l(){i(_,b,v,x,w,A,d,p,h,g,y,m,o,n),k.lineEnd=u,u()}var h,f,d,p,g,y,m,v,_,b,x,w,A,k={point:e,lineStart:r,lineEnd:u,polygonStart:function(){n.polygonStart(),k.lineStart=s},polygonEnd:function(){n.polygonEnd(),k.lineStart=r}};return k}function i(n,e,r,o,s,c,l,h,f,d,p,g,y,m){var v=l-n,_=h-e,b=v*v+_*_;if(b>4*a&&y--){var x=o+d,w=s+p,A=c+g,k=Math.sqrt(x*x+w*w+A*A),E=Math.asin(A/=k),M=pu(pu(A)-1)a||pu((v*T+_*F)/b-.5)>.3||u>o*d+s*p+c*g)&&(i(n,e,r,o,s,c,D,C,M,x/=k,w/=k,A,y,m),m.point(D,C),i(D,C,M,x,w,A,l,h,f,d,p,g,y,m))}}var a=.5,u=Math.cos(30*Nu),o=16;return n.precision=function(t){return arguments.length?(o=(a=t*t)>0&&16,n):Math.sqrt(a)},n}function re(t){var n=ee(function(n,e){return t([n*Pu,e*Pu])});return function(t){return se(n(t))}}function ie(t){this.stream=t}function ae(t,n){return{point:n,sphere:function(){t.sphere()},lineStart:function(){t.lineStart()},lineEnd:function(){t.lineEnd()},polygonStart:function(){t.polygonStart()},polygonEnd:function(){t.polygonEnd()}}}function ue(t){return oe(function(){return t})()}function oe(t){function n(t){return t=o(t[0]*Nu,t[1]*Nu),[t[0]*f+s,c-t[1]*f]}function e(t){return t=o.invert((t[0]-s)/f,(c-t[1])/f),t&&[t[0]*Pu,t[1]*Pu]}function r(){o=Cn(u=he(m,v,b),a);var t=a(g,y);return s=d-t[0]*f,c=p+t[1]*f,i()}function i(){return l&&(l.valid=!1,l=null),n}var a,u,o,s,c,l,h=ee(function(t,n){return t=a(t,n),[t[0]*f+s,c-t[1]*f]}),f=150,d=480,p=250,g=0,y=0,m=0,v=0,b=0,x=Io,w=_,A=null,k=null;return n.stream=function(t){return l&&(l.valid=!1),l=se(x(u,h(w(t)))),l.valid=!0,l},n.clipAngle=function(t){return arguments.length?(x=null==t?(A=t,Io):$n((A=+t)*Nu),i()):A},n.clipExtent=function(t){return arguments.length?(k=t,w=t?zn(t[0][0],t[0][1],t[1][0],t[1][1]):_,i()):k},n.scale=function(t){return arguments.length?(f=+t,r()):f},n.translate=function(t){return arguments.length?(d=+t[0],p=+t[1],r()):[d,p]},n.center=function(t){return arguments.length?(g=t[0]%360*Nu,y=t[1]%360*Nu,r()):[g*Pu,y*Pu]},n.rotate=function(t){return arguments.length?(m=t[0]%360*Nu,v=t[1]%360*Nu,b=t.length>2?t[2]%360*Nu:0,r()):[m*Pu,v*Pu,b*Pu]},eu.rebind(n,h,"precision"),function(){return a=t.apply(this,arguments),n.invert=a.invert&&e,r()}}function se(t){return ae(t,function(n,e){t.point(n*Nu,e*Nu)})}function ce(t,n){return[t,n]}function le(t,n){return[t>Ou?t-Lu:-Ou>t?t+Lu:t,n]}function he(t,n,e){return t?n||e?Cn(de(t),pe(n,e)):de(t):n||e?pe(n,e):le}function fe(t){return function(n,e){return n+=t,[n>Ou?n-Lu:-Ou>n?n+Lu:n,e]}}function de(t){var n=fe(t);return n.invert=fe(-t),n}function pe(t,n){function e(t,n){var e=Math.cos(n),o=Math.cos(t)*e,s=Math.sin(t)*e,c=Math.sin(n),l=c*r+o*i;return[Math.atan2(s*a-l*u,o*r-c*i),et(l*a+s*u)]}var r=Math.cos(t),i=Math.sin(t),a=Math.cos(n),u=Math.sin(n);return e.invert=function(t,n){var e=Math.cos(n),o=Math.cos(t)*e,s=Math.sin(t)*e,c=Math.sin(n),l=c*a-s*u;return[Math.atan2(s*a+c*u,o*r+l*i),et(l*r-o*i)]},e}function ge(t,n){var e=Math.cos(t),r=Math.sin(t);return function(i,a,u,o){var s=u*n;null!=i?(i=ye(e,i),a=ye(e,a),(u>0?a>i:i>a)&&(i+=u*Lu)):(i=t+u*Lu,a=t-.5*s);for(var c,l=i;u>0?l>a:a>l;l-=s)o.point((c=wn([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],c[1])}}function ye(t,n){var e=yn(n);e[0]-=t,xn(e);var r=nt(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Tu)%(2*Math.PI)}function me(t,n,e){var r=eu.range(t,n-Tu,e).concat(n);return function(t){return r.map(function(n){return[t,n]})}}function ve(t,n,e){var r=eu.range(t,n-Tu,e).concat(n);return function(t){return r.map(function(n){return[n,t]})}}function _e(t){return t.source}function be(t){return t.target}function xe(t,n,e,r){var i=Math.cos(n),a=Math.sin(n),u=Math.cos(r),o=Math.sin(r),s=i*Math.cos(t),c=i*Math.sin(t),l=u*Math.cos(e),h=u*Math.sin(e),f=2*Math.asin(Math.sqrt(ut(r-n)+i*u*ut(e-t))),d=1/Math.sin(f),p=f?function(t){var n=Math.sin(t*=f)*d,e=Math.sin(f-t)*d,r=e*s+n*l,i=e*c+n*h,u=e*a+n*o;return[Math.atan2(i,r)*Pu,Math.atan2(u,Math.sqrt(r*r+i*i))*Pu]}:function(){return[t*Pu,n*Pu]};return p.distance=f,p}function we(){function t(t,i){var a=Math.sin(i*=Nu),u=Math.cos(i),o=pu((t*=Nu)-n),s=Math.cos(o);qo+=Math.atan2(Math.sqrt((o=u*Math.sin(o))*o+(o=r*a-e*u*s)*o),e*a+r*u*s),n=t,e=a,r=u}var n,e,r;Go.point=function(i,a){n=i*Nu,e=Math.sin(a*=Nu),r=Math.cos(a),Go.point=t},Go.lineEnd=function(){Go.point=Go.lineEnd=w}}function Ae(t,n){function e(n,e){var r=Math.cos(n),i=Math.cos(e),a=t(r*i);return[a*i*Math.sin(n),a*Math.sin(e)]}return e.invert=function(t,e){var r=Math.sqrt(t*t+e*e),i=n(r),a=Math.sin(i),u=Math.cos(i);return[Math.atan2(t*a,r*u),Math.asin(r&&e*a/r)]},e}function ke(t,n){function e(t,n){u>0?-Bu+Tu>n&&(n=-Bu+Tu):n>Bu-Tu&&(n=Bu-Tu);var e=u/Math.pow(i(n),a);return[e*Math.sin(a*t),u-e*Math.cos(a*t)]}var r=Math.cos(t),i=function(t){return Math.tan(Ou/4+t/2)},a=t===n?Math.sin(t):Math.log(r/Math.cos(n))/Math.log(i(n)/i(t)),u=r*Math.pow(i(t),a)/a;return a?(e.invert=function(t,n){var e=u-n,r=J(a)*Math.sqrt(t*t+e*e);return[Math.atan2(t,e)/a,2*Math.atan(Math.pow(u/r,1/a))-Bu]},e):Me}function Ee(t,n){function e(t,n){var e=a-n;return[e*Math.sin(i*t),a-e*Math.cos(i*t)]}var r=Math.cos(t),i=t===n?Math.sin(t):(r-Math.cos(n))/(n-t),a=r/i+t;return pu(i)i;i++){for(;r>1&&tt(t[e[r-2]],t[e[r-1]],t[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function Oe(t,n){return t[0]-n[0]||t[1]-n[1]}function Le(t,n,e){return(e[0]-n[0])*(t[1]-n[1])<(e[1]-n[1])*(t[0]-n[0])}function Ie(t,n,e,r){var i=t[0],a=e[0],u=n[0]-i,o=r[0]-a,s=t[1],c=e[1],l=n[1]-s,h=r[1]-c,f=(o*(s-c)-h*(i-a))/(h*u-o*l);return[i+f*u,s+f*l]}function Be(t){var n=t[0],e=t[t.length-1];return!(n[0]-e[0]||n[1]-e[1])}function Ne(){rr(this),this.edge=this.site=this.circle=null}function Pe(t){var n=is.pop()||new Ne;return n.site=t,n}function Re(t){Ve(t),ns.remove(t),is.push(t),rr(t)}function je(t){var n=t.circle,e=n.x,r=n.cy,i={x:e,y:r},a=t.P,u=t.N,o=[t];Re(t);for(var s=a;s.circle&&pu(e-s.circle.x)l;++l)c=o[l],s=o[l-1],tr(c.edge,s.site,c.site,i);s=o[0],c=o[h-1],c.edge=Qe(s.site,c.site,null,i),He(s),He(c)}function Ye(t){for(var n,e,r,i,a=t.x,u=t.y,o=ns._;o;)if(r=Ue(o,u)-a,r>Tu)o=o.L;else{if(i=a-$e(o,u),!(i>Tu)){r>-Tu?(n=o.P,e=o):i>-Tu?(n=o,e=o.N):n=e=o;break}if(!o.R){n=o;break}o=o.R}var s=Pe(t);if(ns.insert(n,s),n||e){if(n===e)return Ve(n),e=Pe(n.site),ns.insert(s,e),s.edge=e.edge=Qe(n.site,s.site),He(n),void He(e);if(!e)return void(s.edge=Qe(n.site,s.site));Ve(n),Ve(e);var c=n.site,l=c.x,h=c.y,f=t.x-l,d=t.y-h,p=e.site,g=p.x-l,y=p.y-h,m=2*(f*y-d*g),v=f*f+d*d,_=g*g+y*y,b={x:(y*v-d*_)/m+l,y:(f*_-g*v)/m+h};tr(e.edge,c,p,b),s.edge=Qe(c,t,null,b),e.edge=Qe(t,p,null,b),He(n),He(e)}}function Ue(t,n){var e=t.site,r=e.x,i=e.y,a=i-n;if(!a)return r;var u=t.P;if(!u)return-(1/0);e=u.site;var o=e.x,s=e.y,c=s-n;if(!c)return o;var l=o-r,h=1/a-1/c,f=l/c;return h?(-f+Math.sqrt(f*f-2*h*(l*l/(-2*c)-s+c/2+i-a/2)))/h+r:(r+o)/2}function $e(t,n){var e=t.N;if(e)return Ue(e,n);var r=t.site;return r.y===n?r.x:1/0}function We(t){this.site=t,this.edges=[]}function ze(t){for(var n,e,r,i,a,u,o,s,c,l,h=t[0][0],f=t[1][0],d=t[0][1],p=t[1][1],g=ts,y=g.length;y--;)if(a=g[y],a&&a.prepare())for(o=a.edges,s=o.length,u=0;s>u;)l=o[u].end(),r=l.x,i=l.y,c=o[++u%s].start(),n=c.x,e=c.y,(pu(r-n)>Tu||pu(i-e)>Tu)&&(o.splice(u,0,new nr(Je(a.site,l,pu(r-h)Tu?{x:h,y:pu(n-h)Tu?{x:pu(e-p)Tu?{x:f,y:pu(n-f)Tu?{x:pu(e-d)=-Fu)){var d=s*s+c*c,p=l*l+h*h,g=(h*d-c*p)/f,y=(s*p-l*d)/f,h=y+o,m=as.pop()||new Ge;m.arc=t,m.site=i,m.x=g+u,m.y=h+Math.sqrt(g*g+y*y),m.cy=h,t.circle=m;for(var v=null,_=rs._;_;)if(m.y<_.y||m.y===_.y&&m.x<=_.x){if(!_.L){v=_.P;break}_=_.L}else{if(!_.R){v=_;break}_=_.R}rs.insert(v,m),v||(es=m)}}}}function Ve(t){var n=t.circle;n&&(n.P||(es=n.N),rs.remove(n),as.push(n),rr(n),t.circle=null)}function Ze(t){for(var n,e=Jo,r=Wn(t[0][0],t[0][1],t[1][0],t[1][1]),i=e.length;i--;)n=e[i],(!Xe(n,t)||!r(n)||pu(n.a.x-n.b.x)y||y>=o)return;if(f>p){if(a){if(a.y>=c)return}else a={x:y,y:s};e={x:y,y:c}}else{if(a){if(a.yr||r>1)if(f>p){if(a){if(a.y>=c)return}else a={x:(s-i)/r,y:s};e={x:(c-i)/r,y:c}}else{if(a){if(a.yd){if(a){if(a.x>=o)return}else a={x:u,y:r*u+i};e={x:o,y:r*o+i}}else{if(a){if(a.xa||h>u||r>f||i>d)){if(p=t.point){var p,g=n-t.x,y=e-t.y,m=g*g+y*y;if(s>m){var v=Math.sqrt(s=m);r=n-v,i=e-v,a=n+v,u=e+v,o=p}}for(var _=t.nodes,b=.5*(l+f),x=.5*(h+d),w=n>=b,A=e>=x,k=A<<1|w,E=k+4;E>k;++k)if(t=_[3&k])switch(3&k){case 0:c(t,l,h,b,x);break;case 1:c(t,b,h,f,x);break;case 2:c(t,l,x,b,d);break;case 3:c(t,b,x,f,d)}}}(t,r,i,a,u),o}function gr(t,n){t=eu.rgb(t),n=eu.rgb(n);var e=t.r,r=t.g,i=t.b,a=n.r-e,u=n.g-r,o=n.b-i;return function(t){return"#"+xt(Math.round(e+a*t))+xt(Math.round(r+u*t))+xt(Math.round(i+o*t))}}function yr(t,n){var e,r={},i={};for(e in t)e in n?r[e]=_r(t[e],n[e]):i[e]=t[e];for(e in n)e in t||(i[e]=n[e]);return function(t){for(e in r)i[e]=r[e](t);return i}}function mr(t,n){return t=+t,n=+n,function(e){return t*(1-e)+n*e}}function vr(t,n){var e,r,i,a=os.lastIndex=ss.lastIndex=0,u=-1,o=[],s=[];for(t+="",n+="";(e=os.exec(t))&&(r=ss.exec(n));)(i=r.index)>a&&(i=n.slice(a,i),o[u]?o[u]+=i:o[++u]=i),(e=e[0])===(r=r[0])?o[u]?o[u]+=r:o[++u]=r:(o[++u]=null,s.push({i:u,x:mr(e,r)})),a=ss.lastIndex;return ar;++r)o[(e=s[r]).i]=e.x(t);return o.join("")})}function _r(t,n){for(var e,r=eu.interpolators.length;--r>=0&&!(e=eu.interpolators[r](t,n)););return e}function br(t,n){var e,r=[],i=[],a=t.length,u=n.length,o=Math.min(t.length,n.length);for(e=0;o>e;++e)r.push(_r(t[e],n[e]));for(;a>e;++e)i[e]=t[e];for(;u>e;++e)i[e]=n[e];return function(t){for(e=0;o>e;++e)i[e]=r[e](t);return i}}function xr(t){return function(n){return 0>=n?0:n>=1?1:t(n)}}function wr(t){return function(n){return 1-t(1-n)}}function Ar(t){return function(n){return.5*(.5>n?t(2*n):2-t(2-2*n))}}function kr(t){return t*t}function Er(t){return t*t*t}function Mr(t){if(0>=t)return 0;if(t>=1)return 1;var n=t*t,e=n*t;return 4*(.5>t?e:3*(t-n)+e-.75)}function Sr(t){return function(n){return Math.pow(n,t)}}function Dr(t){return 1-Math.cos(t*Bu)}function Cr(t){return Math.pow(2,10*(t-1))}function Tr(t){return 1-Math.sqrt(1-t*t)}function Fr(t,n){var e;return arguments.length<2&&(n=.45),arguments.length?e=n/Lu*Math.asin(1/t):(t=1,e=n/4),function(r){return 1+t*Math.pow(2,-10*r)*Math.sin((r-e)*Lu/n)}}function Or(t){return t||(t=1.70158),function(n){return n*n*((t+1)*n-t)}}function Lr(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375}function Ir(t,n){t=eu.hcl(t),n=eu.hcl(n);var e=t.h,r=t.c,i=t.l,a=n.h-e,u=n.c-r,o=n.l-i;return isNaN(u)&&(u=0,r=isNaN(r)?n.c:r),isNaN(a)?(a=0,e=isNaN(e)?n.h:e):a>180?a-=360:-180>a&&(a+=360),function(t){return ht(e+a*t,r+u*t,i+o*t)+""}}function Br(t,n){t=eu.hsl(t),n=eu.hsl(n);var e=t.h,r=t.s,i=t.l,a=n.h-e,u=n.s-r,o=n.l-i;return isNaN(u)&&(u=0,r=isNaN(r)?n.s:r),isNaN(a)?(a=0,e=isNaN(e)?n.h:e):a>180?a-=360:-180>a&&(a+=360),function(t){return ct(e+a*t,r+u*t,i+o*t)+""}}function Nr(t,n){t=eu.lab(t),n=eu.lab(n);var e=t.l,r=t.a,i=t.b,a=n.l-e,u=n.a-r,o=n.b-i;return function(t){return dt(e+a*t,r+u*t,i+o*t)+""}}function Pr(t,n){return n-=t,function(e){return Math.round(t+n*e)}}function Rr(t){var n=[t.a,t.b],e=[t.c,t.d],r=Yr(n),i=jr(n,e),a=Yr(Ur(e,n,-i))||0;n[0]*e[1]180?l+=360:l-c>180&&(c+=360),i.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:mr(c,l)})):l&&r.push(r.pop()+"rotate("+l+")"),h!=f?i.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:mr(h,f)}):f&&r.push(r.pop()+"skewX("+f+")"),d[0]!=p[0]||d[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),i.push({i:e-4,x:mr(d[0],p[0])},{i:e-2,x:mr(d[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=i.length,function(t){for(var n,a=-1;++a=0;)e.push(i[r])}function ni(t,n){for(var e=[t],r=[];null!=(t=e.pop());)if(r.push(t),(a=t.children)&&(i=a.length))for(var i,a,u=-1;++ue;++e)(n=t[e][1])>i&&(r=e,i=n);return r}function fi(t){return t.reduce(di,0)}function di(t,n){return t+n[1]}function pi(t,n){return gi(t,Math.ceil(Math.log(n.length)/Math.LN2+1))}function gi(t,n){for(var e=-1,r=+t[0],i=(t[1]-r)/n,a=[];++e<=n;)a[e]=i*e+r;return a}function yi(t){return[eu.min(t),eu.max(t)]}function mi(t,n){return t.value-n.value}function vi(t,n){var e=t._pack_next;t._pack_next=n,n._pack_prev=t,n._pack_next=e,e._pack_prev=n}function _i(t,n){t._pack_next=n,n._pack_prev=t}function bi(t,n){var e=n.x-t.x,r=n.y-t.y,i=t.r+n.r;return.999*i*i>e*e+r*r}function xi(t){function n(t){l=Math.min(t.x-t.r,l),h=Math.max(t.x+t.r,h),f=Math.min(t.y-t.r,f),d=Math.max(t.y+t.r,d)}if((e=t.children)&&(c=e.length)){var e,r,i,a,u,o,s,c,l=1/0,h=-(1/0),f=1/0,d=-(1/0);if(e.forEach(wi),r=e[0],r.x=-r.r,r.y=0,n(r),c>1&&(i=e[1],i.x=i.r,i.y=0,n(i),c>2))for(a=e[2],Ei(r,i,a),n(a),vi(r,a),r._pack_prev=a,vi(a,i),i=r._pack_next,u=3;c>u;u++){Ei(r,i,a=e[u]);var p=0,g=1,y=1;for(o=i._pack_next;o!==i;o=o._pack_next,g++)if(bi(o,a)){p=1;break}if(1==p)for(s=r._pack_prev;s!==o._pack_prev&&!bi(s,a);s=s._pack_prev,y++);p?(y>g||g==y&&i.ru;u++)a=e[u],a.x-=m,a.y-=v,_=Math.max(_,a.r+Math.sqrt(a.x*a.x+a.y*a.y));t.r=_,e.forEach(Ai)}}function wi(t){t._pack_next=t._pack_prev=t}function Ai(t){delete t._pack_next,delete t._pack_prev}function ki(t,n,e,r){var i=t.children;if(t.x=n+=r*t.x,t.y=e+=r*t.y,t.r*=r,i)for(var a=-1,u=i.length;++a=0;)n=i[a],n.z+=e,n.m+=e,e+=n.s+(r+=n.c)}function Fi(t,n,e){return t.a.parent===n.parent?t.a:e}function Oi(t){return 1+eu.max(t,function(t){return t.y})}function Li(t){return t.reduce(function(t,n){return t+n.x},0)/t.length}function Ii(t){var n=t.children;return n&&n.length?Ii(n[0]):t}function Bi(t){var n,e=t.children;return e&&(n=e.length)?Bi(e[n-1]):t}function Ni(t){return{x:t.x,y:t.y,dx:t.dx,dy:t.dy}}function Pi(t,n){var e=t.x+n[3],r=t.y+n[0],i=t.dx-n[1]-n[3],a=t.dy-n[0]-n[2];return 0>i&&(e+=i/2,i=0),0>a&&(r+=a/2,a=0),{x:e,y:r,dx:i,dy:a}}function Ri(t){var n=t[0],e=t[t.length-1];return e>n?[n,e]:[e,n]}function ji(t){return t.rangeExtent?t.rangeExtent():Ri(t.range())}function Yi(t,n,e,r){var i=e(t[0],t[1]),a=r(n[0],n[1]);return function(t){return a(i(t))}}function Ui(t,n){var e,r=0,i=t.length-1,a=t[r],u=t[i];return a>u&&(e=r,r=i,i=e,e=a,a=u,u=e),t[r]=n.floor(a),t[i]=n.ceil(u),t}function $i(t){return t?{floor:function(n){return Math.floor(n/t)*t},ceil:function(n){return Math.ceil(n/t)*t}}:_s}function Wi(t,n,e,r){var i=[],a=[],u=0,o=Math.min(t.length,n.length)-1;for(t[o]2?Wi:Yi,s=r?zr:Wr;return u=i(t,n,s,e),o=i(n,t,s,_r),a}function a(t){return u(t)}var u,o;return a.invert=function(t){return o(t)},a.domain=function(n){return arguments.length?(t=n.map(Number),i()):t},a.range=function(t){return arguments.length?(n=t,i()):n},a.rangeRound=function(t){return a.range(t).interpolate(Pr)},a.clamp=function(t){return arguments.length?(r=t,i()):r},a.interpolate=function(t){return arguments.length?(e=t,i()):e},a.ticks=function(n){return Vi(t,n)},a.tickFormat=function(n,e){return Zi(t,n,e)},a.nice=function(n){return Gi(t,n),i()},a.copy=function(){return zi(t,n,e,r)},i()}function qi(t,n){return eu.rebind(t,n,"range","rangeRound","interpolate","clamp")}function Gi(t,n){return Ui(t,$i(Hi(t,n)[2]))}function Hi(t,n){null==n&&(n=10);var e=Ri(t),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/n)/Math.LN10)),a=n/r*i;return.15>=a?i*=10:.35>=a?i*=5:.75>=a&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Vi(t,n){return eu.range.apply(eu,Hi(t,n))}function Zi(t,n,e){var r=Hi(t,n);if(e){var i=uo.exec(e);if(i.shift(),"s"===i[8]){var a=eu.formatPrefix(Math.max(pu(r[0]),pu(r[1])));return i[7]||(i[7]="."+Xi(a.scale(r[2]))),i[8]="f",e=eu.format(i.join("")),function(t){return e(a.scale(t))+a.symbol}}i[7]||(i[7]="."+Ki(i[8],r)),e=i.join("")}else e=",."+Xi(r[2])+"f";return eu.format(e)}function Xi(t){return-Math.floor(Math.log(t)/Math.LN10+.01)}function Ki(t,n){var e=Xi(n[2]);return t in bs?Math.abs(e-Xi(Math.max(pu(n[0]),pu(n[1]))))+ +("e"!==t):e-2*("%"===t)}function Qi(t,n,e,r){function i(t){return(e?Math.log(0>t?0:t):-Math.log(t>0?0:-t))/Math.log(n)}function a(t){return e?Math.pow(n,t):-Math.pow(n,-t)}function u(n){return t(i(n))}return u.invert=function(n){return a(t.invert(n))},u.domain=function(n){return arguments.length?(e=n[0]>=0,t.domain((r=n.map(Number)).map(i)),u):r},u.base=function(e){return arguments.length?(n=+e,t.domain(r.map(i)),u):n},u.nice=function(){var n=Ui(r.map(i),e?Math:ws);return t.domain(n),r=n.map(a),u},u.ticks=function(){var t=Ri(r),u=[],o=t[0],s=t[1],c=Math.floor(i(o)),l=Math.ceil(i(s)),h=n%1?2:n;if(isFinite(l-c)){if(e){for(;l>c;c++)for(var f=1;h>f;f++)u.push(a(c)*f);u.push(a(c))}else for(u.push(a(c));c++0;f--)u.push(a(c)*f);for(c=0;u[c]s;l--);u=u.slice(c,l)}return u},u.tickFormat=function(t,n){if(!arguments.length)return xs;arguments.length<2?n=xs:"function"!=typeof n&&(n=eu.format(n));var r,o=Math.max(.1,t/u.ticks().length),s=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(t){return t/a(s(i(t)+r))<=o?n(t):""}},u.copy=function(){return Qi(t.copy(),n,e,r)},qi(u,t)}function Ji(t,n,e){function r(n){return t(i(n))}var i=ta(n),a=ta(1/n);return r.invert=function(n){return a(t.invert(n))},r.domain=function(n){return arguments.length?(t.domain((e=n.map(Number)).map(i)),r):e},r.ticks=function(t){return Vi(e,t)},r.tickFormat=function(t,n){return Zi(e,t,n)},r.nice=function(t){return r.domain(Gi(e,t))},r.exponent=function(u){return arguments.length?(i=ta(n=u),a=ta(1/n),t.domain(e.map(i)),r):n},r.copy=function(){return Ji(t.copy(),n,e)},qi(r,t)}function ta(t){return function(n){return 0>n?-Math.pow(-n,t):Math.pow(n,t)}}function na(t,n){function e(e){return a[((i.get(e)||("range"===n.t?i.set(e,t.push(e)):0/0))-1)%a.length]}function r(n,e){return eu.range(t.length).map(function(t){return n+e*t})}var i,a,u;return e.domain=function(r){if(!arguments.length)return t;t=[],i=new l;for(var a,u=-1,o=r.length;++ue?[0/0,0/0]:[e>0?o[e-1]:t[0],en?0/0:n/a+t,[n,n+1/a]},r.copy=function(){return ra(t,n,e)},i()}function ia(t,n){function e(e){return e>=e?n[eu.bisect(t,e)]:void 0}return e.domain=function(n){return arguments.length?(t=n,e):t},e.range=function(t){return arguments.length?(n=t,e):n},e.invertExtent=function(e){return e=n.indexOf(e),[t[e-1],t[e]]},e.copy=function(){return ia(t,n)},e}function aa(t){function n(t){return+t}return n.invert=n,n.domain=n.range=function(e){return arguments.length?(t=e.map(n),n):t},n.ticks=function(n){return Vi(t,n)},n.tickFormat=function(n,e){return Zi(t,n,e)},n.copy=function(){return aa(t)},n}function ua(){return 0}function oa(t){return t.innerRadius}function sa(t){return t.outerRadius}function ca(t){return t.startAngle}function la(t){return t.endAngle}function ha(t){return t&&t.padAngle}function fa(t,n,e,r){return(t-e)*n-(n-r)*t>0?0:1}function da(t,n,e,r,i){var a=t[0]-n[0],u=t[1]-n[1],o=(i?r:-r)/Math.sqrt(a*a+u*u),s=o*u,c=-o*a,l=t[0]+s,h=t[1]+c,f=n[0]+s,d=n[1]+c,p=(l+f)/2,g=(h+d)/2,y=f-l,m=d-h,v=y*y+m*m,_=e-r,b=l*d-f*h,x=(0>m?-1:1)*Math.sqrt(_*_*v-b*b),w=(b*m-y*x)/v,A=(-b*y-m*x)/v,k=(b*m+y*x)/v,E=(-b*y+m*x)/v,M=w-p,S=A-g,D=k-p,C=E-g;return M*M+S*S>D*D+C*C&&(w=k,A=E),[[w-s,A-c],[w*e/_,A*e/_]]}function pa(t){function n(n){function u(){c.push("M",a(t(l),o))}for(var s,c=[],l=[],h=-1,f=n.length,d=St(e),p=St(r);++h1&&i.push("H",r[0]),i.join("")}function va(t){for(var n=0,e=t.length,r=t[0],i=[r[0],",",r[1]];++n1){o=n[1],a=t[s],s++,r+="C"+(i[0]+u[0])+","+(i[1]+u[1])+","+(a[0]-o[0])+","+(a[1]-o[1])+","+a[0]+","+a[1];for(var c=2;c9&&(i=3*n/Math.sqrt(i),u[o]=i*e,u[o+1]=i*r));for(o=-1;++o<=s;)i=(t[Math.min(s,o+1)][0]-t[Math.max(0,o-1)][0])/(6*(1+u[o]*u[o])), -a.push([i||0,u[o]*i||0]);return a}function Ia(t){return t.length<3?ga(t):t[0]+Aa(t,La(t))}function Ba(t){for(var n,e,r,i=-1,a=t.length;++ir)return l();var i=a[a.active];i&&(--a.count,delete a[a.active],i.event&&i.event.interrupt.call(t,t.__data__,i.index)),a.active=r,u.event&&u.event.start.call(t,t.__data__,n),u.tween.forEach(function(e,r){(r=r.call(t,t.__data__,n))&&g.push(r)}),f=u.ease,h=u.duration,eu.timer(function(){return p.c=c(e||1)?Tn:c,1},0,o)}function c(e){if(a.active!==r)return 1;for(var i=e/h,o=f(i),s=g.length;s>0;)g[--s].call(t,o);return i>=1?(u.event&&u.event.end.call(t,t.__data__,n),l()):void 0}function l(){return--a.count?delete a[r]:delete t[e],1}var h,f,d=u.delay,p=ro,g=[];return p.t=d+o,i>=d?s(i-d):void(p.c=s)},0,o)}}function Za(t,n,e){t.attr("transform",function(t){var r=n(t);return"translate("+(isFinite(r)?r:e(t))+",0)"})}function Xa(t,n,e){t.attr("transform",function(t){var r=n(t);return"translate(0,"+(isFinite(r)?r:e(t))+")"})}function Ka(t){return t.toISOString()}function Qa(t,n,e){function r(n){return t(n)}function i(t,e){var r=t[1]-t[0],i=r/e,a=eu.bisect(Hs,i);return a==Hs.length?[n.year,Hi(t.map(function(t){return t/31536e6}),e)[2]]:a?n[i/Hs[a-1]1?{floor:function(n){for(;e(n=t.floor(n));)n=Ja(n-1);return n},ceil:function(n){for(;e(n=t.ceil(n));)n=Ja(+n+1);return n}}:t))},r.ticks=function(t,n){var e=Ri(r.domain()),a=null==t?i(e,10):"number"==typeof t?i(e,t):!t.range&&[{range:t},n];return a&&(t=a[0],n=a[1]),t.range(e[0],Ja(+e[1]+1),1>n?1:n)},r.tickFormat=function(){return e},r.copy=function(){return Qa(t.copy(),n,e)},qi(r,t)}function Ja(t){return new Date(t)}function tu(t){return JSON.parse(t.responseText)}function nu(t){var n=au.createRange();return n.selectNode(au.body),n.createContextualFragment(t.responseText)}var eu={version:"3.5.6"},ru=[].slice,iu=function(t){return ru.call(t)},au=this.document;if(au)try{iu(au.documentElement.childNodes)[0].nodeType}catch(uu){iu=function(t){for(var n=t.length,e=new Array(n);n--;)e[n]=t[n];return e}}if(Date.now||(Date.now=function(){return+new Date}),au)try{au.createElement("DIV").style.setProperty("opacity",0,"")}catch(ou){var su=this.Element.prototype,cu=su.setAttribute,lu=su.setAttributeNS,hu=this.CSSStyleDeclaration.prototype,fu=hu.setProperty;su.setAttribute=function(t,n){cu.call(this,t,n+"")},su.setAttributeNS=function(t,n,e){lu.call(this,t,n,e+"")},hu.setProperty=function(t,n,e){fu.call(this,t,n+"",e)}}eu.ascending=r,eu.descending=function(t,n){return t>n?-1:n>t?1:n>=t?0:0/0},eu.min=function(t,n){var e,r,i=-1,a=t.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ir&&(e=r)}else{for(;++i=r){e=r;break}for(;++ir&&(e=r)}return e},eu.max=function(t,n){var e,r,i=-1,a=t.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ie&&(e=r)}else{for(;++i=r){e=r;break}for(;++ie&&(e=r)}return e},eu.extent=function(t,n){var e,r,i,a=-1,u=t.length;if(1===arguments.length){for(;++a=r){e=i=r;break}for(;++ar&&(e=r),r>i&&(i=r))}else{for(;++a=r){e=i=r;break}for(;++ar&&(e=r),r>i&&(i=r))}return[e,i]},eu.sum=function(t,n){var e,r=0,i=t.length,u=-1;if(1===arguments.length)for(;++u1?s/(l-1):void 0},eu.deviation=function(){var t=eu.variance.apply(this,arguments);return t?Math.sqrt(t):t};var du=u(r);eu.bisectLeft=du.left,eu.bisect=eu.bisectRight=du.right,eu.bisector=function(t){return u(1===t.length?function(n,e){return r(t(n),e)}:t)},eu.shuffle=function(t,n,e){(a=arguments.length)<3&&(e=t.length,2>a&&(n=0));for(var r,i,a=e-n;a;)i=Math.random()*a--|0,r=t[a+n],t[a+n]=t[i+n],t[i+n]=r;return t},eu.permute=function(t,n){for(var e=n.length,r=new Array(e);e--;)r[e]=t[n[e]];return r},eu.pairs=function(t){for(var n,e=0,r=t.length-1,i=t[0],a=new Array(0>r?0:r);r>e;)a[e]=[n=i,i=t[++e]];return a},eu.zip=function(){if(!(r=arguments.length))return[];for(var t=-1,n=eu.min(arguments,o),e=new Array(n);++t=0;)for(r=t[i],n=r.length;--n>=0;)e[--u]=r[n];return e};var pu=Math.abs;eu.range=function(t,n,e){if(arguments.length<3&&(e=1,arguments.length<2&&(n=t,t=0)),(n-t)/e===1/0)throw new Error("infinite range");var r,i=[],a=s(pu(e)),u=-1;if(t*=a,n*=a,e*=a,0>e)for(;(r=t+e*++u)>n;)i.push(r/a);else for(;(r=t+e*++u)=a.length)return r?r.call(i,u):e?u.sort(e):u;for(var s,c,h,f,d=-1,p=u.length,g=a[o++],y=new l;++d=a.length)return t;var r=[],i=u[e++];return t.forEach(function(t,i){r.push({key:t,values:n(i,e)})}),i?r.sort(function(t,n){return i(t.key,n.key)}):r}var e,r,i={},a=[],u=[];return i.map=function(n,e){return t(e,n,0)},i.entries=function(e){return n(t(eu.map,e,0),0)},i.key=function(t){return a.push(t),i},i.sortKeys=function(t){return u[a.length-1]=t,i},i.sortValues=function(t){return e=t,i},i.rollup=function(t){return r=t,i},i},eu.set=function(t){var n=new v;if(t)for(var e=0,r=t.length;r>e;++e)n.add(t[e]);return n},c(v,{has:d,add:function(t){return this._[h(t+="")]=!0,t},remove:p,values:g,size:y,empty:m,forEach:function(t){for(var n in this._)t.call(this,f(n))}}),eu.behavior={},eu.rebind=function(t,n){for(var e,r=1,i=arguments.length;++r=0&&(r=t.slice(e+1),t=t.slice(0,e)),t)return arguments.length<2?this[t].on(r):this[t].on(r,n);if(2===arguments.length){if(null==n)for(t in this)this.hasOwnProperty(t)&&this[t].on(r,null);return this}},eu.event=null,eu.requote=function(t){return t.replace(vu,"\\$&")};var vu=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,_u={}.__proto__?function(t,n){t.__proto__=n}:function(t,n){for(var e in n)t[e]=n[e]},bu=function(t,n){return n.querySelector(t)},xu=function(t,n){return n.querySelectorAll(t)},wu=function(t,n){var e=t.matches||t[x(t,"matchesSelector")];return(wu=function(t,n){return e.call(t,n)})(t,n)};"function"==typeof Sizzle&&(bu=function(t,n){return Sizzle(t,n)[0]||null},xu=Sizzle,wu=Sizzle.matchesSelector),eu.selection=function(){return eu.select(au.documentElement)};var Au=eu.selection.prototype=[];Au.select=function(t){var n,e,r,i,a=[];t=C(t);for(var u=-1,o=this.length;++u=0&&(e=t.slice(0,n),t=t.slice(n+1)),ku.hasOwnProperty(e)?{space:ku[e],local:t}:t}},Au.attr=function(t,n){if(arguments.length<2){if("string"==typeof t){var e=this.node();return t=eu.ns.qualify(t),t.local?e.getAttributeNS(t.space,t.local):e.getAttribute(t)}for(n in t)this.each(F(n,t[n]));return this}return this.each(F(t,n))},Au.classed=function(t,n){if(arguments.length<2){if("string"==typeof t){var e=this.node(),r=(t=I(t)).length,i=-1;if(n=e.classList){for(;++ii){if("string"!=typeof t){2>i&&(n="");for(r in t)this.each(P(r,t[r],n));return this}if(2>i){var a=this.node();return e(a).getComputedStyle(a,null).getPropertyValue(t)}r=""}return this.each(P(t,n,r))},Au.property=function(t,n){if(arguments.length<2){if("string"==typeof t)return this.node()[t];for(n in t)this.each(R(n,t[n]));return this}return this.each(R(t,n))},Au.text=function(t){return arguments.length?this.each("function"==typeof t?function(){var n=t.apply(this,arguments);this.textContent=null==n?"":n}:null==t?function(){this.textContent=""}:function(){this.textContent=t}):this.node().textContent},Au.html=function(t){return arguments.length?this.each("function"==typeof t?function(){var n=t.apply(this,arguments);this.innerHTML=null==n?"":n}:null==t?function(){this.innerHTML=""}:function(){this.innerHTML=t}):this.node().innerHTML},Au.append=function(t){return t=j(t),this.select(function(){return this.appendChild(t.apply(this,arguments))})},Au.insert=function(t,n){return t=j(t),n=C(n),this.select(function(){return this.insertBefore(t.apply(this,arguments),n.apply(this,arguments)||null)})},Au.remove=function(){return this.each(Y)},Au.data=function(t,n){function e(t,e){var r,i,a,u=t.length,h=e.length,f=Math.min(u,h),d=new Array(h),p=new Array(h),g=new Array(u);if(n){var y,m=new l,v=new Array(u);for(r=-1;++rr;++r)p[r]=U(e[r]);for(;u>r;++r)g[r]=t[r]}p.update=d,p.parentNode=d.parentNode=g.parentNode=t.parentNode,o.push(p),s.push(d),c.push(g)}var r,i,a=-1,u=this.length;if(!arguments.length){for(t=new Array(u=(r=this[0]).length);++aa;a++){i.push(n=[]),n.parentNode=(e=this[a]).parentNode;for(var o=0,s=e.length;s>o;o++)(r=e[o])&&t.call(r,r.__data__,o,a)&&n.push(r)}return D(i)},Au.order=function(){for(var t=-1,n=this.length;++t=0;)(e=r[i])&&(a&&a!==e.nextSibling&&a.parentNode.insertBefore(e,a),a=e);return this},Au.sort=function(t){t=W.apply(this,arguments);for(var n=-1,e=this.length;++nt;t++)for(var e=this[t],r=0,i=e.length;i>r;r++){var a=e[r];if(a)return a}return null},Au.size=function(){var t=0;return z(this,function(){++t}),t};var Eu=[];eu.selection.enter=q,eu.selection.enter.prototype=Eu,Eu.append=Au.append,Eu.empty=Au.empty,Eu.node=Au.node,Eu.call=Au.call,Eu.size=Au.size,Eu.select=function(t){for(var n,e,r,i,a,u=[],o=-1,s=this.length;++or){if("string"!=typeof t){2>r&&(n=!1);for(e in t)this.each(H(e,t[e],n));return this}if(2>r)return(r=this.node()["__on"+t])&&r._;e=!1}return this.each(H(t,n,e))};var Mu=eu.map({mouseenter:"mouseover",mouseleave:"mouseout"});au&&Mu.forEach(function(t){"on"+t in au&&Mu.remove(t)});var Su,Du=0;eu.mouse=function(t){return K(t,M())};var Cu=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;eu.touch=function(t,n,e){if(arguments.length<3&&(e=n,n=M().changedTouches),n)for(var r,i=0,a=n.length;a>i;++i)if((r=n[i]).identifier===e)return K(t,r)},eu.behavior.drag=function(){function t(){this.on("mousedown.drag",a).on("touchstart.drag",u)}function n(t,n,e,a,u){return function(){function o(){var t,e,r=n(f,g);r&&(t=r[0]-_[0],e=r[1]-_[1],p|=t|e,_=r,d({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:t,dy:e}))}function s(){n(f,g)&&(m.on(a+y,null).on(u+y,null),v(p&&eu.event.target===h),d({type:"dragend"}))}var c,l=this,h=eu.event.target,f=l.parentNode,d=r.of(l,arguments),p=0,g=t(),y=".drag"+(null==g?"":"-"+g),m=eu.select(e(h)).on(a+y,o).on(u+y,s),v=X(h),_=n(f,g);i?(c=i.apply(l,arguments),c=[c.x-_[0],c.y-_[1]]):c=[0,0],d({type:"dragstart"})}}var r=S(t,"drag","dragstart","dragend"),i=null,a=n(w,eu.mouse,e,"mousemove","mouseup"),u=n(Q,eu.touch,_,"touchmove","touchend");return t.origin=function(n){return arguments.length?(i=n,t):i},eu.rebind(t,r,"on")},eu.touches=function(t,n){return arguments.length<2&&(n=M().touches),n?iu(n).map(function(n){var e=K(t,n);return e.identifier=n.identifier,e}):[]};var Tu=1e-6,Fu=Tu*Tu,Ou=Math.PI,Lu=2*Ou,Iu=Lu-Tu,Bu=Ou/2,Nu=Ou/180,Pu=180/Ou,Ru=Math.SQRT2,ju=2,Yu=4;eu.interpolateZoom=function(t,n){function e(t){var n=t*v;if(m){var e=it(g),u=a/(ju*f)*(e*at(Ru*n+g)-rt(g));return[r+u*c,i+u*l,a*e/it(Ru*n+g)]}return[r+t*c,i+t*l,a*Math.exp(Ru*n)]}var r=t[0],i=t[1],a=t[2],u=n[0],o=n[1],s=n[2],c=u-r,l=o-i,h=c*c+l*l,f=Math.sqrt(h),d=(s*s-a*a+Yu*h)/(2*a*ju*f),p=(s*s-a*a-Yu*h)/(2*s*ju*f),g=Math.log(Math.sqrt(d*d+1)-d),y=Math.log(Math.sqrt(p*p+1)-p),m=y-g,v=(m||Math.log(s/a))/Ru;return e.duration=1e3*v,e},eu.behavior.zoom=function(){function t(t){t.on(F,h).on($u+".zoom",d).on("dblclick.zoom",p).on(I,f)}function n(t){return[(t[0]-k.x)/k.k,(t[1]-k.y)/k.k]}function r(t){return[t[0]*k.k+k.x,t[1]*k.k+k.y]}function i(t){k.k=Math.max(D[0],Math.min(D[1],t))}function a(t,n){n=r(n),k.x+=t[0]-n[0],k.y+=t[1]-n[1]}function u(n,e,r,u){n.__chart__={x:k.x,y:k.y,k:k.k},i(Math.pow(2,u)),a(y=e,r),n=eu.select(n),C>0&&(n=n.transition().duration(C)),n.call(t.event)}function o(){x&&x.domain(b.range().map(function(t){return(t-k.x)/k.k}).map(b.invert)),A&&A.domain(w.range().map(function(t){return(t-k.y)/k.k}).map(w.invert))}function s(t){T++||t({type:"zoomstart"})}function c(t){o(),t({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function l(t){--T||(t({type:"zoomend"}),y=null)}function h(){function t(){h=1,a(eu.mouse(i),d),c(o)}function r(){f.on(O,null).on(L,null),p(h&&eu.event.target===u),l(o)}var i=this,u=eu.event.target,o=B.of(i,arguments),h=0,f=eu.select(e(i)).on(O,t).on(L,r),d=n(eu.mouse(i)),p=X(i);Ps.call(i),s(o)}function f(){function t(){var t=eu.touches(p);return d=k.k,t.forEach(function(t){t.identifier in y&&(y[t.identifier]=n(t))}),t}function e(){var n=eu.event.target;eu.select(n).on(b,r).on(x,o),w.push(n);for(var e=eu.event.changedTouches,i=0,a=e.length;a>i;++i)y[e[i].identifier]=null;var s=t(),c=Date.now();if(1===s.length){if(500>c-_){var l=s[0];u(p,l,y[l.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),E()}_=c}else if(s.length>1){var l=s[0],h=s[1],f=l[0]-h[0],d=l[1]-h[1];m=f*f+d*d}}function r(){var t,n,e,r,u=eu.touches(p);Ps.call(p);for(var o=0,s=u.length;s>o;++o,r=null)if(e=u[o],r=y[e.identifier]){if(n)break;t=e,n=r}if(r){var l=(l=e[0]-t[0])*l+(l=e[1]-t[1])*l,h=m&&Math.sqrt(l/m);t=[(t[0]+e[0])/2,(t[1]+e[1])/2],n=[(n[0]+r[0])/2,(n[1]+r[1])/2],i(h*d)}_=null,a(t,n),c(g)}function o(){if(eu.event.touches.length){for(var n=eu.event.changedTouches,e=0,r=n.length;r>e;++e)delete y[n[e].identifier];for(var i in y)return void t()}eu.selectAll(w).on(v,null),A.on(F,h).on(I,f),M(),l(g)}var d,p=this,g=B.of(p,arguments),y={},m=0,v=".zoom-"+eu.event.changedTouches[0].identifier,b="touchmove"+v,x="touchend"+v,w=[],A=eu.select(p),M=X(p);e(),s(g),A.on(F,null).on(I,e)}function d(){var t=B.of(this,arguments);v?clearTimeout(v):(Ps.call(this),g=n(y=m||eu.mouse(this)),s(t)),v=setTimeout(function(){v=null,l(t)},50),E(),i(Math.pow(2,.002*Uu())*k.k),a(y,g),c(t)}function p(){var t=eu.mouse(this),e=Math.log(k.k)/Math.LN2;u(this,t,n(t),eu.event.shiftKey?Math.ceil(e)-1:Math.floor(e)+1)}var g,y,m,v,_,b,x,w,A,k={x:0,y:0,k:1},M=[960,500],D=Wu,C=250,T=0,F="mousedown.zoom",O="mousemove.zoom",L="mouseup.zoom",I="touchstart.zoom",B=S(t,"zoomstart","zoom","zoomend");return $u||($u="onwheel"in au?(Uu=function(){return-eu.event.deltaY*(eu.event.deltaMode?120:1)},"wheel"):"onmousewheel"in au?(Uu=function(){return eu.event.wheelDelta},"mousewheel"):(Uu=function(){return-eu.event.detail},"MozMousePixelScroll")),t.event=function(t){t.each(function(){var t=B.of(this,arguments),n=k;Bs?eu.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},s(t)}).tween("zoom:zoom",function(){var e=M[0],r=M[1],i=y?y[0]:e/2,a=y?y[1]:r/2,u=eu.interpolateZoom([(i-k.x)/k.k,(a-k.y)/k.k,e/k.k],[(i-n.x)/n.k,(a-n.y)/n.k,e/n.k]);return function(n){var r=u(n),o=e/r[2];this.__chart__=k={x:i-r[0]*o,y:a-r[1]*o,k:o},c(t)}}).each("interrupt.zoom",function(){l(t)}).each("end.zoom",function(){l(t)}):(this.__chart__=k,s(t),c(t),l(t))})},t.translate=function(n){return arguments.length?(k={x:+n[0],y:+n[1],k:k.k},o(),t):[k.x,k.y]},t.scale=function(n){return arguments.length?(k={x:k.x,y:k.y,k:+n},o(),t):k.k},t.scaleExtent=function(n){return arguments.length?(D=null==n?Wu:[+n[0],+n[1]],t):D},t.center=function(n){return arguments.length?(m=n&&[+n[0],+n[1]],t):m},t.size=function(n){return arguments.length?(M=n&&[+n[0],+n[1]],t):M},t.duration=function(n){return arguments.length?(C=+n,t):C},t.x=function(n){return arguments.length?(x=n,b=n.copy(),k={x:0,y:0,k:1},t):x},t.y=function(n){return arguments.length?(A=n,w=n.copy(),k={x:0,y:0,k:1},t):A},eu.rebind(t,B,"on")};var Uu,$u,Wu=[0,1/0];eu.color=ot,ot.prototype.toString=function(){return this.rgb()+""},eu.hsl=st;var zu=st.prototype=new ot;zu.brighter=function(t){return t=Math.pow(.7,arguments.length?t:1),new st(this.h,this.s,this.l/t)},zu.darker=function(t){return t=Math.pow(.7,arguments.length?t:1),new st(this.h,this.s,t*this.l)},zu.rgb=function(){return ct(this.h,this.s,this.l)},eu.hcl=lt;var qu=lt.prototype=new ot;qu.brighter=function(t){return new lt(this.h,this.c,Math.min(100,this.l+Gu*(arguments.length?t:1)))},qu.darker=function(t){return new lt(this.h,this.c,Math.max(0,this.l-Gu*(arguments.length?t:1)))},qu.rgb=function(){return ht(this.h,this.c,this.l).rgb()},eu.lab=ft;var Gu=18,Hu=.95047,Vu=1,Zu=1.08883,Xu=ft.prototype=new ot;Xu.brighter=function(t){return new ft(Math.min(100,this.l+Gu*(arguments.length?t:1)),this.a,this.b)},Xu.darker=function(t){return new ft(Math.max(0,this.l-Gu*(arguments.length?t:1)),this.a,this.b)},Xu.rgb=function(){return dt(this.l,this.a,this.b)},eu.rgb=vt;var Ku=vt.prototype=new ot;Ku.brighter=function(t){t=Math.pow(.7,arguments.length?t:1);var n=this.r,e=this.g,r=this.b,i=30;return n||e||r?(n&&i>n&&(n=i),e&&i>e&&(e=i),r&&i>r&&(r=i),new vt(Math.min(255,n/t),Math.min(255,e/t),Math.min(255,r/t))):new vt(i,i,i)},Ku.darker=function(t){return t=Math.pow(.7,arguments.length?t:1),new vt(t*this.r,t*this.g,t*this.b)},Ku.hsl=function(){return At(this.r,this.g,this.b)},Ku.toString=function(){return"#"+xt(this.r)+xt(this.g)+xt(this.b)};var Qu=eu.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Qu.forEach(function(t,n){Qu.set(t,_t(n))}),eu.functor=St,eu.xhr=Dt(_),eu.dsv=function(t,n){function e(t,e,a){arguments.length<3&&(a=e,e=null);var u=Ct(t,n,null==e?r:i(e),a);return u.row=function(t){return arguments.length?u.response(null==(e=t)?r:i(t)):e},u}function r(t){return e.parse(t.responseText)}function i(t){return function(n){return e.parse(n.responseText,t)}}function a(n){return n.map(u).join(t)}function u(t){return o.test(t)?'"'+t.replace(/\"/g,'""')+'"':t}var o=new RegExp('["'+t+"\n]"),s=t.charCodeAt(0);return e.parse=function(t,n){var r;return e.parseRows(t,function(t,e){if(r)return r(t,e-1);var i=new Function("d","return {"+t.map(function(t,n){return JSON.stringify(t)+": d["+n+"]"}).join(",")+"}");r=n?function(t,e){return n(i(t),e)}:i})},e.parseRows=function(t,n){function e(){if(l>=c)return u;if(i)return i=!1,a;var n=l;if(34===t.charCodeAt(n)){for(var e=n;e++l;){var r=t.charCodeAt(l++),o=1;if(10===r)i=!0;else if(13===r)i=!0,10===t.charCodeAt(l)&&(++l,++o);else if(r!==s)continue;return t.slice(n,l-o)}return t.slice(n)}for(var r,i,a={},u={},o=[],c=t.length,l=0,h=0;(r=e())!==u;){for(var f=[];r!==a&&r!==u;)f.push(r),r=e();n&&null==(f=n(f,h++))||o.push(f)}return o},e.format=function(n){if(Array.isArray(n[0]))return e.formatRows(n);var r=new v,i=[];return n.forEach(function(t){for(var n in t)r.has(n)||i.push(r.add(n))}),[i.map(u).join(t)].concat(n.map(function(n){return i.map(function(t){return u(n[t])}).join(t)})).join("\n")},e.formatRows=function(t){return t.map(a).join("\n")},e},eu.csv=eu.dsv(",","text/csv"),eu.tsv=eu.dsv(" ","text/tab-separated-values");var Ju,to,no,eo,ro,io=this[x(this,"requestAnimationFrame")]||function(t){setTimeout(t,17)};eu.timer=function(t,n,e){var r=arguments.length;2>r&&(n=0),3>r&&(e=Date.now());var i=e+n,a={c:t,t:i,f:!1,n:null};to?to.n=a:Ju=a,to=a,no||(eo=clearTimeout(eo),no=1,io(Ot))},eu.timer.flush=function(){Lt(),It()},eu.round=function(t,n){return n?Math.round(t*(n=Math.pow(10,n)))/n:Math.round(t)};var ao=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"].map(Nt);eu.formatPrefix=function(t,n){var e=0;return t&&(0>t&&(t*=-1),n&&(t=eu.round(t,Bt(t,n))),e=1+Math.floor(1e-12+Math.log(t)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),ao[8+e/3]};var uo=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,oo=eu.map({b:function(t){return t.toString(2)},c:function(t){return String.fromCharCode(t)},o:function(t){return t.toString(8)},x:function(t){return t.toString(16)},X:function(t){return t.toString(16).toUpperCase()},g:function(t,n){return t.toPrecision(n)},e:function(t,n){return t.toExponential(n)},f:function(t,n){return t.toFixed(n)},r:function(t,n){return(t=eu.round(t,Bt(t,n))).toFixed(Math.max(0,Math.min(20,Bt(t*(1+1e-15),n))))}}),so=eu.time={},co=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){lo.setUTCDate.apply(this._,arguments)},setDay:function(){lo.setUTCDay.apply(this._,arguments)},setFullYear:function(){lo.setUTCFullYear.apply(this._,arguments)},setHours:function(){lo.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){lo.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){lo.setUTCMinutes.apply(this._,arguments)},setMonth:function(){lo.setUTCMonth.apply(this._,arguments)},setSeconds:function(){lo.setUTCSeconds.apply(this._,arguments)},setTime:function(){lo.setTime.apply(this._,arguments)}};var lo=Date.prototype;so.year=Yt(function(t){return t=so.day(t),t.setMonth(0,1),t},function(t,n){t.setFullYear(t.getFullYear()+n)},function(t){return t.getFullYear()}),so.years=so.year.range,so.years.utc=so.year.utc.range,so.day=Yt(function(t){var n=new co(2e3,0);return n.setFullYear(t.getFullYear(),t.getMonth(),t.getDate()),n},function(t,n){t.setDate(t.getDate()+n)},function(t){return t.getDate()-1}),so.days=so.day.range,so.days.utc=so.day.utc.range,so.dayOfYear=function(t){var n=so.year(t);return Math.floor((t-n-6e4*(t.getTimezoneOffset()-n.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(t,n){n=7-n;var e=so[t]=Yt(function(t){return(t=so.day(t)).setDate(t.getDate()-(t.getDay()+n)%7),t},function(t,n){t.setDate(t.getDate()+7*Math.floor(n))},function(t){var e=so.year(t).getDay();return Math.floor((so.dayOfYear(t)+(e+n)%7)/7)-(e!==n)});so[t+"s"]=e.range,so[t+"s"].utc=e.utc.range,so[t+"OfYear"]=function(t){var e=so.year(t).getDay();return Math.floor((so.dayOfYear(t)+(e+n)%7)/7); - -}}),so.week=so.sunday,so.weeks=so.sunday.range,so.weeks.utc=so.sunday.utc.range,so.weekOfYear=so.sundayOfYear;var ho={"-":"",_:" ",0:"0"},fo=/^\s*\d+/,po=/^%/;eu.locale=function(t){return{numberFormat:Pt(t),timeFormat:$t(t)}};var go=eu.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});eu.format=go.numberFormat,eu.geo={},ln.prototype={s:0,t:0,add:function(t){hn(t,this.t,yo),hn(yo.s,this.s,this),this.s?this.t+=yo.t:this.s=yo.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var yo=new ln;eu.geo.stream=function(t,n){t&&mo.hasOwnProperty(t.type)?mo[t.type](t,n):fn(t,n)};var mo={Feature:function(t,n){fn(t.geometry,n)},FeatureCollection:function(t,n){for(var e=t.features,r=-1,i=e.length;++rt?4*Ou+t:t,xo.lineStart=xo.lineEnd=xo.point=w}};eu.geo.bounds=function(){function t(t,n){_.push(b=[l=t,f=t]),h>n&&(h=n),n>d&&(d=n)}function n(n,e){var r=yn([n*Nu,e*Nu]);if(m){var i=vn(m,r),a=[i[1],-i[0],0],u=vn(a,i);xn(u),u=wn(u);var s=n-p,c=s>0?1:-1,g=u[0]*Pu*c,y=pu(s)>180;if(y^(g>c*p&&c*n>g)){var v=u[1]*Pu;v>d&&(d=v)}else if(g=(g+360)%360-180,y^(g>c*p&&c*n>g)){var v=-u[1]*Pu;h>v&&(h=v)}else h>e&&(h=e),e>d&&(d=e);y?p>n?o(l,n)>o(l,f)&&(f=n):o(n,f)>o(l,f)&&(l=n):f>=l?(l>n&&(l=n),n>f&&(f=n)):n>p?o(l,n)>o(l,f)&&(f=n):o(n,f)>o(l,f)&&(l=n)}else t(n,e);m=r,p=n}function e(){x.point=n}function r(){b[0]=l,b[1]=f,x.point=t,m=null}function i(t,e){if(m){var r=t-p;v+=pu(r)>180?r+(r>0?360:-360):r}else g=t,y=e;xo.point(t,e),n(t,e)}function a(){xo.lineStart()}function u(){i(g,y),xo.lineEnd(),pu(v)>Tu&&(l=-(f=180)),b[0]=l,b[1]=f,m=null}function o(t,n){return(n-=t)<0?n+360:n}function s(t,n){return t[0]-n[0]}function c(t,n){return n[0]<=n[1]?n[0]<=t&&t<=n[1]:tbo?(l=-(f=180),h=-(d=90)):v>Tu?d=90:-Tu>v&&(h=-90),b[0]=l,b[1]=f}};return function(t){d=f=-(l=h=1/0),_=[],eu.geo.stream(t,x);var n=_.length;if(n){_.sort(s);for(var e,r=1,i=_[0],a=[i];n>r;++r)e=_[r],c(e[0],i)||c(e[1],i)?(o(i[0],e[1])>o(i[0],i[1])&&(i[1]=e[1]),o(e[0],i[1])>o(i[0],i[1])&&(i[0]=e[0])):a.push(i=e);for(var u,e,p=-(1/0),n=a.length-1,r=0,i=a[n];n>=r;i=e,++r)e=a[r],(u=o(i[1],e[0]))>p&&(p=u,l=e[0],f=i[1])}return _=b=null,l===1/0||h===1/0?[[0/0,0/0],[0/0,0/0]]:[[l,h],[f,d]]}}(),eu.geo.centroid=function(t){wo=Ao=ko=Eo=Mo=So=Do=Co=To=Fo=Oo=0,eu.geo.stream(t,Lo);var n=To,e=Fo,r=Oo,i=n*n+e*e+r*r;return Fu>i&&(n=So,e=Do,r=Co,Tu>Ao&&(n=ko,e=Eo,r=Mo),i=n*n+e*e+r*r,Fu>i)?[0/0,0/0]:[Math.atan2(e,n)*Pu,et(r/Math.sqrt(i))*Pu]};var wo,Ao,ko,Eo,Mo,So,Do,Co,To,Fo,Oo,Lo={sphere:w,point:kn,lineStart:Mn,lineEnd:Sn,polygonStart:function(){Lo.lineStart=Dn},polygonEnd:function(){Lo.lineStart=Mn}},Io=In(Tn,Rn,Yn,[-Ou,-Ou/2]),Bo=1e9;eu.geo.clipExtent=function(){var t,n,e,r,i,a,u={stream:function(t){return i&&(i.valid=!1),i=a(t),i.valid=!0,i},extent:function(o){return arguments.length?(a=zn(t=+o[0][0],n=+o[0][1],e=+o[1][0],r=+o[1][1]),i&&(i.valid=!1,i=null),u):[[t,n],[e,r]]}};return u.extent([[0,0],[960,500]])},(eu.geo.conicEqualArea=function(){return qn(Gn)}).raw=Gn,eu.geo.albers=function(){return eu.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},eu.geo.albersUsa=function(){function t(t){var a=t[0],u=t[1];return n=null,e(a,u),n||(r(a,u),n)||i(a,u),n}var n,e,r,i,a=eu.geo.albers(),u=eu.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),o=eu.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),s={point:function(t,e){n=[t,e]}};return t.invert=function(t){var n=a.scale(),e=a.translate(),r=(t[0]-e[0])/n,i=(t[1]-e[1])/n;return(i>=.12&&.234>i&&r>=-.425&&-.214>r?u:i>=.166&&.234>i&&r>=-.214&&-.115>r?o:a).invert(t)},t.stream=function(t){var n=a.stream(t),e=u.stream(t),r=o.stream(t);return{point:function(t,i){n.point(t,i),e.point(t,i),r.point(t,i)},sphere:function(){n.sphere(),e.sphere(),r.sphere()},lineStart:function(){n.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){n.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){n.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){n.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},t.precision=function(n){return arguments.length?(a.precision(n),u.precision(n),o.precision(n),t):a.precision()},t.scale=function(n){return arguments.length?(a.scale(n),u.scale(.35*n),o.scale(n),t.translate(a.translate())):a.scale()},t.translate=function(n){if(!arguments.length)return a.translate();var c=a.scale(),l=+n[0],h=+n[1];return e=a.translate(n).clipExtent([[l-.455*c,h-.238*c],[l+.455*c,h+.238*c]]).stream(s).point,r=u.translate([l-.307*c,h+.201*c]).clipExtent([[l-.425*c+Tu,h+.12*c+Tu],[l-.214*c-Tu,h+.234*c-Tu]]).stream(s).point,i=o.translate([l-.205*c,h+.212*c]).clipExtent([[l-.214*c+Tu,h+.166*c+Tu],[l-.115*c-Tu,h+.234*c-Tu]]).stream(s).point,t},t.scale(1070)};var No,Po,Ro,jo,Yo,Uo,$o={point:w,lineStart:w,lineEnd:w,polygonStart:function(){Po=0,$o.lineStart=Hn},polygonEnd:function(){$o.lineStart=$o.lineEnd=$o.point=w,No+=pu(Po/2)}},Wo={point:Vn,lineStart:w,lineEnd:w,polygonStart:w,polygonEnd:w},zo={point:Kn,lineStart:Qn,lineEnd:Jn,polygonStart:function(){zo.lineStart=te},polygonEnd:function(){zo.point=Kn,zo.lineStart=Qn,zo.lineEnd=Jn}};eu.geo.path=function(){function t(t){return t&&("function"==typeof o&&a.pointRadius(+o.apply(this,arguments)),u&&u.valid||(u=i(a)),eu.geo.stream(t,u)),a.result()}function n(){return u=null,t}var e,r,i,a,u,o=4.5;return t.area=function(t){return No=0,eu.geo.stream(t,i($o)),No},t.centroid=function(t){return ko=Eo=Mo=So=Do=Co=To=Fo=Oo=0,eu.geo.stream(t,i(zo)),Oo?[To/Oo,Fo/Oo]:Co?[So/Co,Do/Co]:Mo?[ko/Mo,Eo/Mo]:[0/0,0/0]},t.bounds=function(t){return Yo=Uo=-(Ro=jo=1/0),eu.geo.stream(t,i(Wo)),[[Ro,jo],[Yo,Uo]]},t.projection=function(t){return arguments.length?(i=(e=t)?t.stream||re(t):_,n()):e},t.context=function(t){return arguments.length?(a=null==(r=t)?new Zn:new ne(t),"function"!=typeof o&&a.pointRadius(o),n()):r},t.pointRadius=function(n){return arguments.length?(o="function"==typeof n?n:(a.pointRadius(+n),+n),t):o},t.projection(eu.geo.albersUsa()).context(null)},eu.geo.transform=function(t){return{stream:function(n){var e=new ie(n);for(var r in t)e[r]=t[r];return e}}},ie.prototype={point:function(t,n){this.stream.point(t,n)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},eu.geo.projection=ue,eu.geo.projectionMutator=oe,(eu.geo.equirectangular=function(){return ue(ce)}).raw=ce.invert=ce,eu.geo.rotation=function(t){function n(n){return n=t(n[0]*Nu,n[1]*Nu),n[0]*=Pu,n[1]*=Pu,n}return t=he(t[0]%360*Nu,t[1]*Nu,t.length>2?t[2]*Nu:0),n.invert=function(n){return n=t.invert(n[0]*Nu,n[1]*Nu),n[0]*=Pu,n[1]*=Pu,n},n},le.invert=ce,eu.geo.circle=function(){function t(){var t="function"==typeof r?r.apply(this,arguments):r,n=he(-t[0]*Nu,-t[1]*Nu,0).invert,i=[];return e(null,null,1,{point:function(t,e){i.push(t=n(t,e)),t[0]*=Pu,t[1]*=Pu}}),{type:"Polygon",coordinates:[i]}}var n,e,r=[0,0],i=6;return t.origin=function(n){return arguments.length?(r=n,t):r},t.angle=function(r){return arguments.length?(e=ge((n=+r)*Nu,i*Nu),t):n},t.precision=function(r){return arguments.length?(e=ge(n*Nu,(i=+r)*Nu),t):i},t.angle(90)},eu.geo.distance=function(t,n){var e,r=(n[0]-t[0])*Nu,i=t[1]*Nu,a=n[1]*Nu,u=Math.sin(r),o=Math.cos(r),s=Math.sin(i),c=Math.cos(i),l=Math.sin(a),h=Math.cos(a);return Math.atan2(Math.sqrt((e=h*u)*e+(e=c*l-s*h*o)*e),s*l+c*h*o)},eu.geo.graticule=function(){function t(){return{type:"MultiLineString",coordinates:n()}}function n(){return eu.range(Math.ceil(a/y)*y,i,y).map(f).concat(eu.range(Math.ceil(c/m)*m,s,m).map(d)).concat(eu.range(Math.ceil(r/p)*p,e,p).filter(function(t){return pu(t%y)>Tu}).map(l)).concat(eu.range(Math.ceil(o/g)*g,u,g).filter(function(t){return pu(t%m)>Tu}).map(h))}var e,r,i,a,u,o,s,c,l,h,f,d,p=10,g=p,y=90,m=360,v=2.5;return t.lines=function(){return n().map(function(t){return{type:"LineString",coordinates:t}})},t.outline=function(){return{type:"Polygon",coordinates:[f(a).concat(d(s).slice(1),f(i).reverse().slice(1),d(c).reverse().slice(1))]}},t.extent=function(n){return arguments.length?t.majorExtent(n).minorExtent(n):t.minorExtent()},t.majorExtent=function(n){return arguments.length?(a=+n[0][0],i=+n[1][0],c=+n[0][1],s=+n[1][1],a>i&&(n=a,a=i,i=n),c>s&&(n=c,c=s,s=n),t.precision(v)):[[a,c],[i,s]]},t.minorExtent=function(n){return arguments.length?(r=+n[0][0],e=+n[1][0],o=+n[0][1],u=+n[1][1],r>e&&(n=r,r=e,e=n),o>u&&(n=o,o=u,u=n),t.precision(v)):[[r,o],[e,u]]},t.step=function(n){return arguments.length?t.majorStep(n).minorStep(n):t.minorStep()},t.majorStep=function(n){return arguments.length?(y=+n[0],m=+n[1],t):[y,m]},t.minorStep=function(n){return arguments.length?(p=+n[0],g=+n[1],t):[p,g]},t.precision=function(n){return arguments.length?(v=+n,l=me(o,u,90),h=ve(r,e,v),f=me(c,s,90),d=ve(a,i,v),t):v},t.majorExtent([[-180,-90+Tu],[180,90-Tu]]).minorExtent([[-180,-80-Tu],[180,80+Tu]])},eu.geo.greatArc=function(){function t(){return{type:"LineString",coordinates:[n||r.apply(this,arguments),e||i.apply(this,arguments)]}}var n,e,r=_e,i=be;return t.distance=function(){return eu.geo.distance(n||r.apply(this,arguments),e||i.apply(this,arguments))},t.source=function(e){return arguments.length?(r=e,n="function"==typeof e?null:e,t):r},t.target=function(n){return arguments.length?(i=n,e="function"==typeof n?null:n,t):i},t.precision=function(){return arguments.length?t:0},t},eu.geo.interpolate=function(t,n){return xe(t[0]*Nu,t[1]*Nu,n[0]*Nu,n[1]*Nu)},eu.geo.length=function(t){return qo=0,eu.geo.stream(t,Go),qo};var qo,Go={sphere:w,point:w,lineStart:we,lineEnd:w,polygonStart:w,polygonEnd:w},Ho=Ae(function(t){return Math.sqrt(2/(1+t))},function(t){return 2*Math.asin(t/2)});(eu.geo.azimuthalEqualArea=function(){return ue(Ho)}).raw=Ho;var Vo=Ae(function(t){var n=Math.acos(t);return n&&n/Math.sin(n)},_);(eu.geo.azimuthalEquidistant=function(){return ue(Vo)}).raw=Vo,(eu.geo.conicConformal=function(){return qn(ke)}).raw=ke,(eu.geo.conicEquidistant=function(){return qn(Ee)}).raw=Ee;var Zo=Ae(function(t){return 1/t},Math.atan);(eu.geo.gnomonic=function(){return ue(Zo)}).raw=Zo,Me.invert=function(t,n){return[t,2*Math.atan(Math.exp(n))-Bu]},(eu.geo.mercator=function(){return Se(Me)}).raw=Me;var Xo=Ae(function(){return 1},Math.asin);(eu.geo.orthographic=function(){return ue(Xo)}).raw=Xo;var Ko=Ae(function(t){return 1/(1+t)},function(t){return 2*Math.atan(t)});(eu.geo.stereographic=function(){return ue(Ko)}).raw=Ko,De.invert=function(t,n){return[-n,2*Math.atan(Math.exp(t))-Bu]},(eu.geo.transverseMercator=function(){var t=Se(De),n=t.center,e=t.rotate;return t.center=function(t){return t?n([-t[1],t[0]]):(t=n(),[t[1],-t[0]])},t.rotate=function(t){return t?e([t[0],t[1],t.length>2?t[2]+90:90]):(t=e(),[t[0],t[1],t[2]-90])},e([0,0,90])}).raw=De,eu.geom={},eu.geom.hull=function(t){function n(t){if(t.length<3)return[];var n,i=St(e),a=St(r),u=t.length,o=[],s=[];for(n=0;u>n;n++)o.push([+i.call(this,t[n],n),+a.call(this,t[n],n),n]);for(o.sort(Oe),n=0;u>n;n++)s.push([o[n][0],-o[n][1]]);var c=Fe(o),l=Fe(s),h=l[0]===c[0],f=l[l.length-1]===c[c.length-1],d=[];for(n=c.length-1;n>=0;--n)d.push(t[o[c[n]][2]]);for(n=+h;n=r&&c.x<=a&&c.y>=i&&c.y<=u?[[r,u],[a,u],[a,i],[r,i]]:[];l.point=t[o]}),n}function e(t){return t.map(function(t,n){return{x:Math.round(a(t,n)/Tu)*Tu,y:Math.round(u(t,n)/Tu)*Tu,i:n}})}var r=Ce,i=Te,a=r,u=i,o=us;return t?n(t):(n.links=function(t){return or(e(t)).edges.filter(function(t){return t.l&&t.r}).map(function(n){return{source:t[n.l.i],target:t[n.r.i]}})},n.triangles=function(t){var n=[];return or(e(t)).cells.forEach(function(e,r){for(var i,a,u=e.site,o=e.edges.sort(qe),s=-1,c=o.length,l=o[c-1].edge,h=l.l===u?l.r:l.l;++s=c,f=r>=l,d=f<<1|h;t.leaf=!1,t=t.nodes[d]||(t.nodes[d]=fr()),h?i=c:o=c,f?u=l:s=l,a(t,n,e,r,i,u,o,s)}var l,h,f,d,p,g,y,m,v,_=St(o),b=St(s);if(null!=n)g=n,y=e,m=r,v=i;else if(m=v=-(g=y=1/0),h=[],f=[],p=t.length,u)for(d=0;p>d;++d)l=t[d],l.xm&&(m=l.x),l.y>v&&(v=l.y),h.push(l.x),f.push(l.y);else for(d=0;p>d;++d){var x=+_(l=t[d],d),w=+b(l,d);g>x&&(g=x),y>w&&(y=w),x>m&&(m=x),w>v&&(v=w),h.push(x),f.push(w)}var A=m-g,k=v-y;A>k?v=y+A:m=g+k;var E=fr();if(E.add=function(t){a(E,t,+_(t,++d),+b(t,d),g,y,m,v)},E.visit=function(t){dr(t,E,g,y,m,v)},E.find=function(t){return pr(E,t[0],t[1],g,y,m,v)},d=-1,null==n){for(;++d=0?t.slice(0,n):t,r=n>=0?t.slice(n+1):"in";return e=ls.get(e)||cs,r=hs.get(r)||_,xr(r(e.apply(null,ru.call(arguments,1))))},eu.interpolateHcl=Ir,eu.interpolateHsl=Br,eu.interpolateLab=Nr,eu.interpolateRound=Pr,eu.transform=function(t){var n=au.createElementNS(eu.ns.prefix.svg,"g");return(eu.transform=function(t){if(null!=t){n.setAttribute("transform",t);var e=n.transform.baseVal.consolidate()}return new Rr(e?e.matrix:fs)})(t)},Rr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var fs={a:1,b:0,c:0,d:1,e:0,f:0};eu.interpolateTransform=$r,eu.layout={},eu.layout.bundle=function(){return function(t){for(var n=[],e=-1,r=t.length;++eo*o/y){if(p>s){var c=n.charge/s;t.px-=a*c,t.py-=u*c}return!0}if(n.point&&s&&p>s){var c=n.pointCharge/s;t.px-=a*c,t.py-=u*c}}return!n.charge}}function n(t){t.px=eu.event.x,t.py=eu.event.y,o.resume()}var e,r,i,a,u,o={},s=eu.dispatch("start","tick","end"),c=[1,1],l=.9,h=ds,f=ps,d=-30,p=gs,g=.1,y=.64,m=[],v=[];return o.tick=function(){if((r*=.99)<.005)return s.end({type:"end",alpha:r=0}),!0;var n,e,o,h,f,p,y,_,b,x=m.length,w=v.length;for(e=0;w>e;++e)o=v[e],h=o.source,f=o.target,_=f.x-h.x,b=f.y-h.y,(p=_*_+b*b)&&(p=r*a[e]*((p=Math.sqrt(p))-i[e])/p,_*=p,b*=p,f.x-=_*(y=h.weight/(f.weight+h.weight)),f.y-=b*y,h.x+=_*(y=1-y),h.y+=b*y);if((y=r*g)&&(_=c[0]/2,b=c[1]/2,e=-1,y))for(;++e0?t:0:t>0&&(s.start({type:"start",alpha:r=t}),eu.timer(o.tick)),o):r},o.start=function(){function t(t,r){if(!e){for(e=new Array(s),o=0;s>o;++o)e[o]=[];for(o=0;l>o;++o){var i=v[o];e[i.source.index].push(i.target),e[i.target.index].push(i.source)}}for(var a,u=e[n],o=-1,c=u.length;++on;++n)(r=m[n]).index=n,r.weight=0;for(n=0;l>n;++n)r=v[n],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(n=0;s>n;++n)r=m[n],isNaN(r.x)&&(r.x=t("x",p)),isNaN(r.y)&&(r.y=t("y",g)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(i=[],"function"==typeof h)for(n=0;l>n;++n)i[n]=+h.call(this,v[n],n);else for(n=0;l>n;++n)i[n]=h;if(a=[],"function"==typeof f)for(n=0;l>n;++n)a[n]=+f.call(this,v[n],n);else for(n=0;l>n;++n)a[n]=f;if(u=[],"function"==typeof d)for(n=0;s>n;++n)u[n]=+d.call(this,m[n],n);else for(n=0;s>n;++n)u[n]=d;return o.resume()},o.resume=function(){return o.alpha(.1)},o.stop=function(){return o.alpha(0)},o.drag=function(){return e||(e=eu.behavior.drag().origin(_).on("dragstart.force",Vr).on("drag.force",n).on("dragend.force",Zr)),arguments.length?void this.on("mouseover.force",Xr).on("mouseout.force",Kr).call(e):e},eu.rebind(o,s,"on")};var ds=20,ps=1,gs=1/0;eu.layout.hierarchy=function(){function t(i){var a,u=[i],o=[];for(i.depth=0;null!=(a=u.pop());)if(o.push(a),(c=e.call(t,a,a.depth))&&(s=c.length)){for(var s,c,l;--s>=0;)u.push(l=c[s]),l.parent=a,l.depth=a.depth+1;r&&(a.value=0),a.children=c}else r&&(a.value=+r.call(t,a,a.depth)||0),delete a.children;return ni(i,function(t){var e,i;n&&(e=t.children)&&e.sort(n),r&&(i=t.parent)&&(i.value+=t.value)}),o}var n=ii,e=ei,r=ri;return t.sort=function(e){return arguments.length?(n=e,t):n},t.children=function(n){return arguments.length?(e=n,t):e},t.value=function(n){return arguments.length?(r=n,t):r},t.revalue=function(n){return r&&(ti(n,function(t){t.children&&(t.value=0)}),ni(n,function(n){var e;n.children||(n.value=+r.call(t,n,n.depth)||0),(e=n.parent)&&(e.value+=n.value)})),n},t},eu.layout.partition=function(){function t(n,e,r,i){var a=n.children;if(n.x=e,n.y=n.depth*i,n.dx=r,n.dy=i,a&&(u=a.length)){var u,o,s,c=-1;for(r=n.value?r/n.value:0;++ch?-1:1),p=(h-s*d)/eu.sum(c),g=eu.range(s),y=[];return null!=e&&g.sort(e===ys?function(t,n){return c[n]-c[t]}:function(t,n){return e(u[t],u[n])}),g.forEach(function(t){y[t]={data:u[t],value:o=c[t],startAngle:l,endAngle:l+=o*p+d,padAngle:f}}),y}var n=Number,e=ys,r=0,i=Lu,a=0;return t.value=function(e){return arguments.length?(n=e,t):n},t.sort=function(n){return arguments.length?(e=n,t):e},t.startAngle=function(n){return arguments.length?(r=n,t):r},t.endAngle=function(n){return arguments.length?(i=n,t):i},t.padAngle=function(n){return arguments.length?(a=n,t):a},t};var ys={};eu.layout.stack=function(){function t(o,s){if(!(f=o.length))return o;var c=o.map(function(e,r){return n.call(t,e,r)}),l=c.map(function(n){return n.map(function(n,e){return[a.call(t,n,e),u.call(t,n,e)]})}),h=e.call(t,l,s);c=eu.permute(c,h),l=eu.permute(l,h);var f,d,p,g,y=r.call(t,l,s),m=c[0].length;for(p=0;m>p;++p)for(i.call(t,c[0][p],g=y[p],l[0][p][1]),d=1;f>d;++d)i.call(t,c[d][p],g+=l[d-1][p][1],l[d][p][1]);return o}var n=_,e=ci,r=li,i=si,a=ui,u=oi;return t.values=function(e){return arguments.length?(n=e,t):n},t.order=function(n){return arguments.length?(e="function"==typeof n?n:ms.get(n)||ci,t):e},t.offset=function(n){return arguments.length?(r="function"==typeof n?n:vs.get(n)||li,t):r},t.x=function(n){return arguments.length?(a=n,t):a},t.y=function(n){return arguments.length?(u=n,t):u},t.out=function(n){return arguments.length?(i=n,t):i},t};var ms=eu.map({"inside-out":function(t){var n,e,r=t.length,i=t.map(hi),a=t.map(fi),u=eu.range(r).sort(function(t,n){return i[t]-i[n]}),o=0,s=0,c=[],l=[];for(n=0;r>n;++n)e=u[n],s>o?(o+=a[e],c.push(e)):(s+=a[e],l.push(e));return l.reverse().concat(c)},reverse:function(t){return eu.range(t.length).reverse()},"default":ci}),vs=eu.map({silhouette:function(t){var n,e,r,i=t.length,a=t[0].length,u=[],o=0,s=[];for(e=0;a>e;++e){for(n=0,r=0;i>n;n++)r+=t[n][e][1];r>o&&(o=r),u.push(r)}for(e=0;a>e;++e)s[e]=(o-u[e])/2;return s},wiggle:function(t){var n,e,r,i,a,u,o,s,c,l=t.length,h=t[0],f=h.length,d=[];for(d[0]=s=c=0,e=1;f>e;++e){for(n=0,i=0;l>n;++n)i+=t[n][e][1];for(n=0,a=0,o=h[e][0]-h[e-1][0];l>n;++n){for(r=0,u=(t[n][e][1]-t[n][e-1][1])/(2*o);n>r;++r)u+=(t[r][e][1]-t[r][e-1][1])/o;a+=u*t[n][e][1]}d[e]=s-=i?a/i*o:0,c>s&&(c=s)}for(e=0;f>e;++e)d[e]-=c;return d},expand:function(t){var n,e,r,i=t.length,a=t[0].length,u=1/i,o=[];for(e=0;a>e;++e){for(n=0,r=0;i>n;n++)r+=t[n][e][1];if(r)for(n=0;i>n;n++)t[n][e][1]/=r;else for(n=0;i>n;n++)t[n][e][1]=u}for(e=0;a>e;++e)o[e]=0;return o},zero:li});eu.layout.histogram=function(){function t(t,a){for(var u,o,s=[],c=t.map(e,this),l=r.call(this,c,a),h=i.call(this,l,c,a),a=-1,f=c.length,d=h.length-1,p=n?1:1/f;++a0)for(a=-1;++a=l[0]&&o<=l[1]&&(u=s[eu.bisect(h,o,1,d)-1],u.y+=p,u.push(t[a]));return s}var n=!0,e=Number,r=yi,i=pi;return t.value=function(n){return arguments.length?(e=n,t):e},t.range=function(n){return arguments.length?(r=St(n),t):r},t.bins=function(n){return arguments.length?(i="number"==typeof n?function(t){return gi(t,n)}:St(n),t):i},t.frequency=function(e){return arguments.length?(n=!!e,t):n},t},eu.layout.pack=function(){function t(t,a){var u=e.call(this,t,a),o=u[0],s=i[0],c=i[1],l=null==n?Math.sqrt:"function"==typeof n?n:function(){return n};if(o.x=o.y=0,ni(o,function(t){t.r=+l(t.value)}),ni(o,xi),r){var h=r*(n?1:Math.max(2*o.r/s,2*o.r/c))/2;ni(o,function(t){t.r+=h}),ni(o,xi),ni(o,function(t){t.r-=h})}return ki(o,s/2,c/2,n?1:1/Math.max(2*o.r/s,2*o.r/c)),u}var n,e=eu.layout.hierarchy().sort(mi),r=0,i=[1,1];return t.size=function(n){return arguments.length?(i=n,t):i},t.radius=function(e){return arguments.length?(n=null==e||"function"==typeof e?e:+e,t):n},t.padding=function(n){return arguments.length?(r=+n,t):r},Jr(t,e)},eu.layout.tree=function(){function t(t,i){var l=u.call(this,t,i),h=l[0],f=n(h);if(ni(f,e),f.parent.m=-f.z,ti(f,r),c)ti(h,a);else{var d=h,p=h,g=h;ti(h,function(t){t.xp.x&&(p=t),t.depth>g.depth&&(g=t)});var y=o(d,p)/2-d.x,m=s[0]/(p.x+o(p,d)/2+y),v=s[1]/(g.depth||1);ti(h,function(t){t.x=(t.x+y)*m,t.y=t.depth*v})}return l}function n(t){for(var n,e={A:null,children:[t]},r=[e];null!=(n=r.pop());)for(var i,a=n.children,u=0,o=a.length;o>u;++u)r.push((a[u]=i={_:a[u],parent:n,children:(i=a[u].children)&&i.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:u}).a=i);return e.children[0]}function e(t){var n=t.children,e=t.parent.children,r=t.i?e[t.i-1]:null;if(n.length){Ti(t);var a=(n[0].z+n[n.length-1].z)/2;r?(t.z=r.z+o(t._,r._),t.m=t.z-a):t.z=a}else r&&(t.z=r.z+o(t._,r._));t.parent.A=i(t,r,t.parent.A||e[0])}function r(t){t._.x=t.z+t.parent.m,t.m+=t.parent.m}function i(t,n,e){if(n){for(var r,i=t,a=t,u=n,s=i.parent.children[0],c=i.m,l=a.m,h=u.m,f=s.m;u=Di(u),i=Si(i),u&&i;)s=Si(s),a=Di(a),a.a=t,r=u.z+h-i.z-c+o(u._,i._),r>0&&(Ci(Fi(u,t,e),t,r),c+=r,l+=r),h+=u.m,c+=i.m,f+=s.m,l+=a.m;u&&!Di(a)&&(a.t=u,a.m+=h-l),i&&!Si(s)&&(s.t=i,s.m+=c-f,e=t)}return e}function a(t){t.x*=s[0],t.y=t.depth*s[1]}var u=eu.layout.hierarchy().sort(null).value(null),o=Mi,s=[1,1],c=null;return t.separation=function(n){return arguments.length?(o=n,t):o},t.size=function(n){return arguments.length?(c=null==(s=n)?a:null,t):c?null:s},t.nodeSize=function(n){return arguments.length?(c=null==(s=n)?null:a,t):c?s:null},Jr(t,u)},eu.layout.cluster=function(){function t(t,a){var u,o=n.call(this,t,a),s=o[0],c=0;ni(s,function(t){var n=t.children;n&&n.length?(t.x=Li(n),t.y=Oi(n)):(t.x=u?c+=e(t,u):0,t.y=0,u=t)});var l=Ii(s),h=Bi(s),f=l.x-e(l,h)/2,d=h.x+e(h,l)/2;return ni(s,i?function(t){t.x=(t.x-s.x)*r[0],t.y=(s.y-t.y)*r[1]}:function(t){t.x=(t.x-f)/(d-f)*r[0],t.y=(1-(s.y?t.y/s.y:1))*r[1]}),o}var n=eu.layout.hierarchy().sort(null).value(null),e=Mi,r=[1,1],i=!1;return t.separation=function(n){return arguments.length?(e=n,t):e},t.size=function(n){return arguments.length?(i=null==(r=n),t):i?null:r},t.nodeSize=function(n){return arguments.length?(i=null!=(r=n),t):i?r:null},Jr(t,n)},eu.layout.treemap=function(){function t(t,n){for(var e,r,i=-1,a=t.length;++in?0:n),e.area=isNaN(r)||0>=r?0:r}function n(e){var a=e.children;if(a&&a.length){var u,o,s,c=h(e),l=[],f=a.slice(),p=1/0,g="slice"===d?c.dx:"dice"===d?c.dy:"slice-dice"===d?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(t(f,c.dx*c.dy/e.value),l.area=0;(s=f.length)>0;)l.push(u=f[s-1]),l.area+=u.area,"squarify"!==d||(o=r(l,g))<=p?(f.pop(),p=o):(l.area-=l.pop().area,i(l,g,c,!1),g=Math.min(c.dx,c.dy),l.length=l.area=0,p=1/0);l.length&&(i(l,g,c,!0),l.length=l.area=0),a.forEach(n)}}function e(n){var r=n.children;if(r&&r.length){ -var a,u=h(n),o=r.slice(),s=[];for(t(o,u.dx*u.dy/n.value),s.area=0;a=o.pop();)s.push(a),s.area+=a.area,null!=a.z&&(i(s,a.z?u.dx:u.dy,u,!o.length),s.length=s.area=0);r.forEach(e)}}function r(t,n){for(var e,r=t.area,i=0,a=1/0,u=-1,o=t.length;++ue&&(a=e),e>i&&(i=e));return r*=r,n*=n,r?Math.max(n*i*p/r,r/(n*a*p)):1/0}function i(t,n,e,r){var i,a=-1,u=t.length,o=e.x,c=e.y,l=n?s(t.area/n):0;if(n==e.dx){for((r||l>e.dy)&&(l=e.dy);++ae.dx)&&(l=e.dx);++ae&&(n=1),1>e&&(t=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return t+n*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var t=eu.random.normal.apply(eu,arguments);return function(){return Math.exp(t())}},bates:function(t){var n=eu.random.irwinHall(t);return function(){return n()/t}},irwinHall:function(t){return function(){for(var n=0,e=0;t>e;e++)n+=Math.random();return n}}},eu.scale={};var _s={floor:_,ceil:_};eu.scale.linear=function(){return zi([0,1],[0,1],_r,!1)};var bs={s:1,g:1,p:1,r:1,e:1};eu.scale.log=function(){return Qi(eu.scale.linear().domain([0,1]),10,!0,[1,10])};var xs=eu.format(".0e"),ws={floor:function(t){return-Math.ceil(-t)},ceil:function(t){return-Math.floor(-t)}};eu.scale.pow=function(){return Ji(eu.scale.linear(),1,[0,1])},eu.scale.sqrt=function(){return eu.scale.pow().exponent(.5)},eu.scale.ordinal=function(){return na([],{t:"range",a:[[]]})},eu.scale.category10=function(){return eu.scale.ordinal().range(As)},eu.scale.category20=function(){return eu.scale.ordinal().range(ks)},eu.scale.category20b=function(){return eu.scale.ordinal().range(Es)},eu.scale.category20c=function(){return eu.scale.ordinal().range(Ms)};var As=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(bt),ks=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(bt),Es=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(bt),Ms=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(bt);eu.scale.quantile=function(){return ea([],[])},eu.scale.quantize=function(){return ra(0,1,[0,1])},eu.scale.threshold=function(){return ia([.5],[0,1])},eu.scale.identity=function(){return aa([0,1])},eu.svg={},eu.svg.arc=function(){function t(){var t=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),l=u.apply(this,arguments)-Bu,h=o.apply(this,arguments)-Bu,f=Math.abs(h-l),d=l>h?0:1;if(t>c&&(p=c,c=t,t=p),f>=Iu)return n(c,d)+(t?n(t,1-d):"")+"Z";var p,g,y,m,v,_,b,x,w,A,k,E,M=0,S=0,D=[];if((m=(+s.apply(this,arguments)||0)/2)&&(y=a===Ss?Math.sqrt(t*t+c*c):+a.apply(this,arguments),d||(S*=-1),c&&(S=et(y/c*Math.sin(m))),t&&(M=et(y/t*Math.sin(m)))),c){v=c*Math.cos(l+S),_=c*Math.sin(l+S),b=c*Math.cos(h-S),x=c*Math.sin(h-S);var C=Math.abs(h-l-2*S)<=Ou?0:1;if(S&&fa(v,_,b,x)===d^C){var T=(l+h)/2;v=c*Math.cos(T),_=c*Math.sin(T),b=x=null}}else v=_=0;if(t){w=t*Math.cos(h-M),A=t*Math.sin(h-M),k=t*Math.cos(l+M),E=t*Math.sin(l+M);var F=Math.abs(l-h+2*M)<=Ou?0:1;if(M&&fa(w,A,k,E)===1-d^F){var O=(l+h)/2;w=t*Math.cos(O),A=t*Math.sin(O),k=E=null}}else w=A=0;if((p=Math.min(Math.abs(c-t)/2,+i.apply(this,arguments)))>.001){g=c>t^d?0:1;var L=null==k?[w,A]:null==b?[v,_]:Ie([v,_],[k,E],[b,x],[w,A]),I=v-L[0],B=_-L[1],N=b-L[0],P=x-L[1],R=1/Math.sin(Math.acos((I*N+B*P)/(Math.sqrt(I*I+B*B)*Math.sqrt(N*N+P*P)))/2),j=Math.sqrt(L[0]*L[0]+L[1]*L[1]);if(null!=b){var Y=Math.min(p,(c-j)/(R+1)),U=da(null==k?[w,A]:[k,E],[v,_],c,Y,d),$=da([b,x],[w,A],c,Y,d);p===Y?D.push("M",U[0],"A",Y,",",Y," 0 0,",g," ",U[1],"A",c,",",c," 0 ",1-d^fa(U[1][0],U[1][1],$[1][0],$[1][1]),",",d," ",$[1],"A",Y,",",Y," 0 0,",g," ",$[0]):D.push("M",U[0],"A",Y,",",Y," 0 1,",g," ",$[0])}else D.push("M",v,",",_);if(null!=k){var W=Math.min(p,(t-j)/(R-1)),z=da([v,_],[k,E],t,-W,d),q=da([w,A],null==b?[v,_]:[b,x],t,-W,d);p===W?D.push("L",q[0],"A",W,",",W," 0 0,",g," ",q[1],"A",t,",",t," 0 ",d^fa(q[1][0],q[1][1],z[1][0],z[1][1]),",",1-d," ",z[1],"A",W,",",W," 0 0,",g," ",z[0]):D.push("L",q[0],"A",W,",",W," 0 0,",g," ",z[0])}else D.push("L",w,",",A)}else D.push("M",v,",",_),null!=b&&D.push("A",c,",",c," 0 ",C,",",d," ",b,",",x),D.push("L",w,",",A),null!=k&&D.push("A",t,",",t," 0 ",F,",",1-d," ",k,",",E);return D.push("Z"),D.join("")}function n(t,n){return"M0,"+t+"A"+t+","+t+" 0 1,"+n+" 0,"+-t+"A"+t+","+t+" 0 1,"+n+" 0,"+t}var e=oa,r=sa,i=ua,a=Ss,u=ca,o=la,s=ha;return t.innerRadius=function(n){return arguments.length?(e=St(n),t):e},t.outerRadius=function(n){return arguments.length?(r=St(n),t):r},t.cornerRadius=function(n){return arguments.length?(i=St(n),t):i},t.padRadius=function(n){return arguments.length?(a=n==Ss?Ss:St(n),t):a},t.startAngle=function(n){return arguments.length?(u=St(n),t):u},t.endAngle=function(n){return arguments.length?(o=St(n),t):o},t.padAngle=function(n){return arguments.length?(s=St(n),t):s},t.centroid=function(){var t=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,n=(+u.apply(this,arguments)+ +o.apply(this,arguments))/2-Bu;return[Math.cos(n)*t,Math.sin(n)*t]},t};var Ss="auto";eu.svg.line=function(){return pa(_)};var Ds=eu.map({linear:ga,"linear-closed":ya,step:ma,"step-before":va,"step-after":_a,basis:Ea,"basis-open":Ma,"basis-closed":Sa,bundle:Da,cardinal:wa,"cardinal-open":ba,"cardinal-closed":xa,monotone:Ia});Ds.forEach(function(t,n){n.key=t,n.closed=/-closed$/.test(t)});var Cs=[0,2/3,1/3,0],Ts=[0,1/3,2/3,0],Fs=[0,1/6,2/3,1/6];eu.svg.line.radial=function(){var t=pa(Ba);return t.radius=t.x,delete t.x,t.angle=t.y,delete t.y,t},va.reverse=_a,_a.reverse=va,eu.svg.area=function(){return Na(_)},eu.svg.area.radial=function(){var t=Na(Ba);return t.radius=t.x,delete t.x,t.innerRadius=t.x0,delete t.x0,t.outerRadius=t.x1,delete t.x1,t.angle=t.y,delete t.y,t.startAngle=t.y0,delete t.y0,t.endAngle=t.y1,delete t.y1,t},eu.svg.chord=function(){function t(t,o){var s=n(this,a,t,o),c=n(this,u,t,o);return"M"+s.p0+r(s.r,s.p1,s.a1-s.a0)+(e(s,c)?i(s.r,s.p1,s.r,s.p0):i(s.r,s.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+i(c.r,c.p1,s.r,s.p0))+"Z"}function n(t,n,e,r){var i=n.call(t,e,r),a=o.call(t,i,r),u=s.call(t,i,r)-Bu,l=c.call(t,i,r)-Bu;return{r:a,a0:u,a1:l,p0:[a*Math.cos(u),a*Math.sin(u)],p1:[a*Math.cos(l),a*Math.sin(l)]}}function e(t,n){return t.a0==n.a0&&t.a1==n.a1}function r(t,n,e){return"A"+t+","+t+" 0 "+ +(e>Ou)+",1 "+n}function i(t,n,e,r){return"Q 0,0 "+r}var a=_e,u=be,o=Pa,s=ca,c=la;return t.radius=function(n){return arguments.length?(o=St(n),t):o},t.source=function(n){return arguments.length?(a=St(n),t):a},t.target=function(n){return arguments.length?(u=St(n),t):u},t.startAngle=function(n){return arguments.length?(s=St(n),t):s},t.endAngle=function(n){return arguments.length?(c=St(n),t):c},t},eu.svg.diagonal=function(){function t(t,i){var a=n.call(this,t,i),u=e.call(this,t,i),o=(a.y+u.y)/2,s=[a,{x:a.x,y:o},{x:u.x,y:o},u];return s=s.map(r),"M"+s[0]+"C"+s[1]+" "+s[2]+" "+s[3]}var n=_e,e=be,r=Ra;return t.source=function(e){return arguments.length?(n=St(e),t):n},t.target=function(n){return arguments.length?(e=St(n),t):e},t.projection=function(n){return arguments.length?(r=n,t):r},t},eu.svg.diagonal.radial=function(){var t=eu.svg.diagonal(),n=Ra,e=t.projection;return t.projection=function(t){return arguments.length?e(ja(n=t)):n},t},eu.svg.symbol=function(){function t(t,r){return(Os.get(n.call(this,t,r))||$a)(e.call(this,t,r))}var n=Ua,e=Ya;return t.type=function(e){return arguments.length?(n=St(e),t):n},t.size=function(n){return arguments.length?(e=St(n),t):e},t};var Os=eu.map({circle:$a,cross:function(t){var n=Math.sqrt(t/5)/2;return"M"+-3*n+","+-n+"H"+-n+"V"+-3*n+"H"+n+"V"+-n+"H"+3*n+"V"+n+"H"+n+"V"+3*n+"H"+-n+"V"+n+"H"+-3*n+"Z"},diamond:function(t){var n=Math.sqrt(t/(2*Is)),e=n*Is;return"M0,"+-n+"L"+e+",0 0,"+n+" "+-e+",0Z"},square:function(t){var n=Math.sqrt(t)/2;return"M"+-n+","+-n+"L"+n+","+-n+" "+n+","+n+" "+-n+","+n+"Z"},"triangle-down":function(t){var n=Math.sqrt(t/Ls),e=n*Ls/2;return"M0,"+e+"L"+n+","+-e+" "+-n+","+-e+"Z"},"triangle-up":function(t){var n=Math.sqrt(t/Ls),e=n*Ls/2;return"M0,"+-e+"L"+n+","+e+" "+-n+","+e+"Z"}});eu.svg.symbolTypes=Os.keys();var Ls=Math.sqrt(3),Is=Math.tan(30*Nu);Au.transition=function(t){for(var n,e,r=Bs||++js,i=Ha(t),a=[],u=Ns||{time:Date.now(),ease:Mr,delay:0,duration:250},o=-1,s=this.length;++oa;a++){i.push(n=[]);for(var e=this[a],o=0,s=e.length;s>o;o++)(r=e[o])&&t.call(r,r.__data__,o,a)&&n.push(r)}return za(i,this.namespace,this.id)},Rs.tween=function(t,n){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(t):z(this,null==n?function(n){n[r][e].tween.remove(t)}:function(i){i[r][e].tween.set(t,n)})},Rs.attr=function(t,n){function e(){this.removeAttribute(o)}function r(){this.removeAttributeNS(o.space,o.local)}function i(t){return null==t?e:(t+="",function(){var n,e=this.getAttribute(o);return e!==t&&(n=u(e,t),function(t){this.setAttribute(o,n(t))})})}function a(t){return null==t?r:(t+="",function(){var n,e=this.getAttributeNS(o.space,o.local);return e!==t&&(n=u(e,t),function(t){this.setAttributeNS(o.space,o.local,n(t))})})}if(arguments.length<2){for(n in t)this.attr(n,t[n]);return this}var u="transform"==t?$r:_r,o=eu.ns.qualify(t);return qa(this,"attr."+t,n,o.local?a:i)},Rs.attrTween=function(t,n){function e(t,e){var r=n.call(this,t,e,this.getAttribute(i));return r&&function(t){this.setAttribute(i,r(t))}}function r(t,e){var r=n.call(this,t,e,this.getAttributeNS(i.space,i.local));return r&&function(t){this.setAttributeNS(i.space,i.local,r(t))}}var i=eu.ns.qualify(t);return this.tween("attr."+t,i.local?r:e)},Rs.style=function(t,n,r){function i(){this.style.removeProperty(t)}function a(n){return null==n?i:(n+="",function(){var i,a=e(this).getComputedStyle(this,null).getPropertyValue(t);return a!==n&&(i=_r(a,n),function(n){this.style.setProperty(t,i(n),r)})})}var u=arguments.length;if(3>u){if("string"!=typeof t){2>u&&(n="");for(r in t)this.style(r,t[r],n);return this}r=""}return qa(this,"style."+t,n,a)},Rs.styleTween=function(t,n,r){function i(i,a){var u=n.call(this,i,a,e(this).getComputedStyle(this,null).getPropertyValue(t));return u&&function(n){this.style.setProperty(t,u(n),r)}}return arguments.length<3&&(r=""),this.tween("style."+t,i)},Rs.text=function(t){return qa(this,"text",t,Ga)},Rs.remove=function(){var t=this.namespace;return this.each("end.transition",function(){var n;this[t].count<2&&(n=this.parentNode)&&n.removeChild(this)})},Rs.ease=function(t){var n=this.id,e=this.namespace;return arguments.length<1?this.node()[e][n].ease:("function"!=typeof t&&(t=eu.ease.apply(eu,arguments)),z(this,function(r){r[e][n].ease=t}))},Rs.delay=function(t){var n=this.id,e=this.namespace;return arguments.length<1?this.node()[e][n].delay:z(this,"function"==typeof t?function(r,i,a){r[e][n].delay=+t.call(r,r.__data__,i,a)}:(t=+t,function(r){r[e][n].delay=t}))},Rs.duration=function(t){var n=this.id,e=this.namespace;return arguments.length<1?this.node()[e][n].duration:z(this,"function"==typeof t?function(r,i,a){r[e][n].duration=Math.max(1,t.call(r,r.__data__,i,a))}:(t=Math.max(1,t),function(r){r[e][n].duration=t}))},Rs.each=function(t,n){var e=this.id,r=this.namespace;if(arguments.length<2){var i=Ns,a=Bs;try{Bs=e,z(this,function(n,i,a){Ns=n[r][e],t.call(n,n.__data__,i,a)})}finally{Ns=i,Bs=a}}else z(this,function(i){var a=i[r][e];(a.event||(a.event=eu.dispatch("start","end","interrupt"))).on(t,n)});return this},Rs.transition=function(){for(var t,n,e,r,i=this.id,a=++js,u=this.namespace,o=[],s=0,c=this.length;c>s;s++){o.push(t=[]);for(var n=this[s],l=0,h=n.length;h>l;l++)(e=n[l])&&(r=e[u][i],Va(e,l,u,a,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),t.push(e)}return za(o,u,a)},eu.svg.axis=function(){function t(t){t.each(function(){var t,c=eu.select(this),l=this.__chart__||e,h=this.__chart__=e.copy(),f=null==s?h.ticks?h.ticks.apply(h,o):h.domain():s,d=null==n?h.tickFormat?h.tickFormat.apply(h,o):_:n,p=c.selectAll(".tick").data(f,h),g=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Tu),y=eu.transition(p.exit()).style("opacity",Tu).remove(),m=eu.transition(p.order()).style("opacity",1),v=Math.max(i,0)+u,b=ji(h),x=c.selectAll(".domain").data([0]),w=(x.enter().append("path").attr("class","domain"),eu.transition(x));g.append("line"),g.append("text");var A,k,E,M,S=g.select("line"),D=m.select("line"),C=p.select("text").text(d),T=g.select("text"),F=m.select("text"),O="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(t=Za,A="x",E="y",k="x2",M="y2",C.attr("dy",0>O?"0em":".71em").style("text-anchor","middle"),w.attr("d","M"+b[0]+","+O*a+"V0H"+b[1]+"V"+O*a)):(t=Xa,A="y",E="x",k="y2",M="x2",C.attr("dy",".32em").style("text-anchor",0>O?"end":"start"),w.attr("d","M"+O*a+","+b[0]+"H0V"+b[1]+"H"+O*a)),S.attr(M,O*i),T.attr(E,O*v),D.attr(k,0).attr(M,O*i),F.attr(A,0).attr(E,O*v),h.rangeBand){var L=h,I=L.rangeBand()/2;l=h=function(t){return L(t)+I}}else l.rangeBand?l=h:y.call(t,h,l);g.call(t,l,h),m.call(t,h,h)})}var n,e=eu.scale.linear(),r=Ys,i=6,a=6,u=3,o=[10],s=null;return t.scale=function(n){return arguments.length?(e=n,t):e},t.orient=function(n){return arguments.length?(r=n in Us?n+"":Ys,t):r},t.ticks=function(){return arguments.length?(o=arguments,t):o},t.tickValues=function(n){return arguments.length?(s=n,t):s},t.tickFormat=function(e){return arguments.length?(n=e,t):n},t.tickSize=function(n){var e=arguments.length;return e?(i=+n,a=+arguments[e-1],t):i},t.innerTickSize=function(n){return arguments.length?(i=+n,t):i},t.outerTickSize=function(n){return arguments.length?(a=+n,t):a},t.tickPadding=function(n){return arguments.length?(u=+n,t):u},t.tickSubdivide=function(){return arguments.length&&t},t};var Ys="bottom",Us={top:1,right:1,bottom:1,left:1};eu.svg.brush=function(){function t(e){e.each(function(){var e=eu.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",a).on("touchstart.brush",a),u=e.selectAll(".background").data([0]);u.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),e.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var o=e.selectAll(".resize").data(g,_);o.exit().remove(),o.enter().append("g").attr("class",function(t){return"resize "+t}).style("cursor",function(t){return $s[t]}).append("rect").attr("x",function(t){return/[ew]$/.test(t)?-3:null}).attr("y",function(t){return/^[ns]/.test(t)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),o.style("display",t.empty()?"none":null);var s,h=eu.transition(e),f=eu.transition(u);c&&(s=ji(c),f.attr("x",s[0]).attr("width",s[1]-s[0]),r(h)),l&&(s=ji(l),f.attr("y",s[0]).attr("height",s[1]-s[0]),i(h)),n(h)})}function n(t){t.selectAll(".resize").attr("transform",function(t){return"translate("+h[+/e$/.test(t)]+","+f[+/^s/.test(t)]+")"})}function r(t){t.select(".extent").attr("x",h[0]),t.selectAll(".extent,.n>rect,.s>rect").attr("width",h[1]-h[0])}function i(t){t.select(".extent").attr("y",f[0]),t.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function a(){function a(){32==eu.event.keyCode&&(C||(_=null,F[0]-=h[1],F[1]-=f[1],C=2),E())}function g(){32==eu.event.keyCode&&2==C&&(F[0]+=h[1],F[1]+=f[1],C=0,E())}function y(){var t=eu.mouse(x),e=!1;b&&(t[0]+=b[0],t[1]+=b[1]),C||(eu.event.altKey?(_||(_=[(h[0]+h[1])/2,(f[0]+f[1])/2]),F[0]=h[+(t[0]<_[0])],F[1]=f[+(t[1]<_[1])]):_=null),S&&m(t,c,0)&&(r(k),e=!0),D&&m(t,l,1)&&(i(k),e=!0),e&&(n(k),A({type:"brush",mode:C?"move":"resize"}))}function m(t,n,e){var r,i,a=ji(n),s=a[0],c=a[1],l=F[e],g=e?f:h,y=g[1]-g[0];return C&&(s-=l,c-=y+l),r=(e?p:d)?Math.max(s,Math.min(c,t[e])):t[e],C?i=(r+=l)+y:(_&&(l=Math.max(s,Math.min(c,2*_[e]-r))),r>l?(i=r,r=l):i=l),g[0]!=r||g[1]!=i?(e?o=null:u=null,g[0]=r,g[1]=i,!0):void 0}function v(){y(),k.style("pointer-events","all").selectAll(".resize").style("display",t.empty()?"none":null),eu.select("body").style("cursor",null),O.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),T(),A({type:"brushend"})}var _,b,x=this,w=eu.select(eu.event.target),A=s.of(x,arguments),k=eu.select(x),M=w.datum(),S=!/^(n|s)$/.test(M)&&c,D=!/^(e|w)$/.test(M)&&l,C=w.classed("extent"),T=X(x),F=eu.mouse(x),O=eu.select(e(x)).on("keydown.brush",a).on("keyup.brush",g);if(eu.event.changedTouches?O.on("touchmove.brush",y).on("touchend.brush",v):O.on("mousemove.brush",y).on("mouseup.brush",v),k.interrupt().selectAll("*").interrupt(),C)F[0]=h[0]-F[0],F[1]=f[0]-F[1];else if(M){var L=+/w$/.test(M),I=+/^n/.test(M);b=[h[1-L]-F[0],f[1-I]-F[1]],F[0]=h[L],F[1]=f[I]}else eu.event.altKey&&(_=F.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),eu.select("body").style("cursor",w.style("cursor")),A({type:"brushstart"}),y()}var u,o,s=S(t,"brushstart","brush","brushend"),c=null,l=null,h=[0,0],f=[0,0],d=!0,p=!0,g=Ws[0];return t.event=function(t){t.each(function(){var t=s.of(this,arguments),n={x:h,y:f,i:u,j:o},e=this.__chart__||n;this.__chart__=n,Bs?eu.select(this).transition().each("start.brush",function(){u=e.i,o=e.j,h=e.x,f=e.y,t({type:"brushstart"})}).tween("brush:brush",function(){var e=br(h,n.x),r=br(f,n.y);return u=o=null,function(i){h=n.x=e(i),f=n.y=r(i),t({type:"brush",mode:"resize"})}}).each("end.brush",function(){u=n.i,o=n.j,t({type:"brush",mode:"resize"}),t({type:"brushend"})}):(t({type:"brushstart"}),t({type:"brush",mode:"resize"}),t({type:"brushend"}))})},t.x=function(n){return arguments.length?(c=n,g=Ws[!c<<1|!l],t):c},t.y=function(n){return arguments.length?(l=n,g=Ws[!c<<1|!l],t):l},t.clamp=function(n){return arguments.length?(c&&l?(d=!!n[0],p=!!n[1]):c?d=!!n:l&&(p=!!n),t):c&&l?[d,p]:c?d:l?p:null},t.extent=function(n){var e,r,i,a,s;return arguments.length?(c&&(e=n[0],r=n[1],l&&(e=e[0],r=r[0]),u=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(s=e,e=r,r=s),(e!=h[0]||r!=h[1])&&(h=[e,r])),l&&(i=n[0],a=n[1],c&&(i=i[1],a=a[1]),o=[i,a],l.invert&&(i=l(i),a=l(a)),i>a&&(s=i,i=a,a=s),(i!=f[0]||a!=f[1])&&(f=[i,a])),t):(c&&(u?(e=u[0],r=u[1]):(e=h[0],r=h[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(s=e,e=r,r=s))),l&&(o?(i=o[0],a=o[1]):(i=f[0],a=f[1],l.invert&&(i=l.invert(i),a=l.invert(a)),i>a&&(s=i,i=a,a=s))),c&&l?[[e,i],[r,a]]:c?[e,r]:l&&[i,a])},t.clear=function(){return t.empty()||(h=[0,0],f=[0,0],u=o=null),t},t.empty=function(){return!!c&&h[0]==h[1]||!!l&&f[0]==f[1]},eu.rebind(t,s,"on")};var $s={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Ws=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],zs=so.format=go.timeFormat,qs=zs.utc,Gs=qs("%Y-%m-%dT%H:%M:%S.%LZ");zs.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Ka:Gs,Ka.parse=function(t){var n=new Date(t);return isNaN(n)?null:n},Ka.toString=Gs.toString,so.second=Yt(function(t){return new co(1e3*Math.floor(t/1e3))},function(t,n){t.setTime(t.getTime()+1e3*Math.floor(n))},function(t){return t.getSeconds()}),so.seconds=so.second.range,so.seconds.utc=so.second.utc.range,so.minute=Yt(function(t){return new co(6e4*Math.floor(t/6e4))},function(t,n){t.setTime(t.getTime()+6e4*Math.floor(n))},function(t){return t.getMinutes()}),so.minutes=so.minute.range,so.minutes.utc=so.minute.utc.range,so.hour=Yt(function(t){var n=t.getTimezoneOffset()/60;return new co(36e5*(Math.floor(t/36e5-n)+n))},function(t,n){t.setTime(t.getTime()+36e5*Math.floor(n))},function(t){return t.getHours()}),so.hours=so.hour.range,so.hours.utc=so.hour.utc.range,so.month=Yt(function(t){return t=so.day(t),t.setDate(1),t},function(t,n){t.setMonth(t.getMonth()+n)},function(t){return t.getMonth()}),so.months=so.month.range,so.months.utc=so.month.utc.range;var Hs=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Vs=[[so.second,1],[so.second,5],[so.second,15],[so.second,30],[so.minute,1],[so.minute,5],[so.minute,15],[so.minute,30],[so.hour,1],[so.hour,3],[so.hour,6],[so.hour,12],[so.day,1],[so.day,2],[so.week,1],[so.month,1],[so.month,3],[so.year,1]],Zs=zs.multi([[".%L",function(t){return t.getMilliseconds()}],[":%S",function(t){return t.getSeconds()}],["%I:%M",function(t){return t.getMinutes()}],["%I %p",function(t){return t.getHours()}],["%a %d",function(t){return t.getDay()&&1!=t.getDate()}],["%b %d",function(t){return 1!=t.getDate()}],["%B",function(t){return t.getMonth()}],["%Y",Tn]]),Xs={range:function(t,n,e){return eu.range(Math.ceil(t/e)*e,+n,e).map(Ja)},floor:_,ceil:_};Vs.year=so.year,so.scale=function(){return Qa(eu.scale.linear(),Vs,Zs)};var Ks=Vs.map(function(t){return[t[0].utc,t[1]]}),Qs=qs.multi([[".%L",function(t){return t.getUTCMilliseconds()}],[":%S",function(t){return t.getUTCSeconds()}],["%I:%M",function(t){return t.getUTCMinutes()}],["%I %p",function(t){return t.getUTCHours()}],["%a %d",function(t){return t.getUTCDay()&&1!=t.getUTCDate()}],["%b %d",function(t){return 1!=t.getUTCDate()}],["%B",function(t){return t.getUTCMonth()}],["%Y",Tn]]);Ks.year=so.year.utc,so.scale.utc=function(){return Qa(eu.scale.linear(),Ks,Qs)},eu.text=Dt(function(t){return t.responseText}),eu.json=function(t,n){return Ct(t,"application/json",tu,n)},eu.html=function(t,n){return Ct(t,"text/html",nu,n)},eu.xml=Dt(function(t){return t.responseXML}),"function"==typeof define&&define.amd?define(eu):"object"==typeof n&&n.exports&&(n.exports=eu),this.d3=eu}()},{}],3:[function(t,n){n.exports={graphlib:t("./lib/graphlib"),dagre:t("./lib/dagre"),intersect:t("./lib/intersect"),render:t("./lib/render"),util:t("./lib/util"),version:t("./lib/version")}},{"./lib/dagre":10,"./lib/graphlib":11,"./lib/intersect":12,"./lib/render":27,"./lib/util":29,"./lib/version":30}],4:[function(t,n){function e(t,n,e,r){var i=t.append("marker").attr("id",n).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerUnits","strokeWidth").attr("markerWidth",8).attr("markerHeight",6).attr("orient","auto"),u=i.append("path").attr("d","M 0 0 L 10 5 L 0 10 z").style("stroke-width",1).style("stroke-dasharray","1,0");a.applyStyle(u,e[r+"Style"])}function r(t,n,e,r){var i=t.append("marker").attr("id",n).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerUnits","strokeWidth").attr("markerWidth",8).attr("markerHeight",6).attr("orient","auto"),u=i.append("path").attr("d","M 0 0 L 10 5 L 0 10 L 4 5 z").style("stroke-width",1).style("stroke-dasharray","1,0");a.applyStyle(u,e[r+"Style"])}function i(t,n,e,r){var i=t.append("marker").attr("id",n).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerUnits","strokeWidth").attr("markerWidth",8).attr("markerHeight",6).attr("orient","auto"),u=i.append("path").attr("d","M 0 5 L 10 5").style("stroke-width",1).style("stroke-dasharray","1,0");a.applyStyle(u,e[r+"Style"])}var a=t("./util");n.exports={"default":e,normal:e,vee:r,undirected:i}},{"./util":29}],5:[function(t,n){function e(t,n){var e=n.nodes().filter(function(t){return r.isSubgraph(n,t)}),a=t.selectAll("g.cluster").data(e,function(t){return t});return a.selectAll("*").remove(),a.enter().append("g").attr("class","cluster").attr("id",function(t){var e=n.node(t);return e.id}).style("opacity",0),r.applyTransition(a,n).style("opacity",1),a.each(function(t){var e=n.node(t),r=d3.select(this);d3.select(this).append("rect");var a=r.append("g").attr("class","label");i(a,e,e.clusterLabelPos)}),a.selectAll("rect").each(function(t){var e=n.node(t),i=d3.select(this);r.applyStyle(i,e.style)}),r.applyTransition(a.exit(),n).style("opacity",0).remove(),a}var r=t("./util"),i=t("./label/add-label");n.exports=e},{"./label/add-label":20,"./util":29}],6:[function(t,n){"use strict";function e(t,n){var e=t.selectAll("g.edgeLabel").data(n.edges(),function(t){return a.edgeToId(t)}).classed("update",!0);return e.selectAll("*").remove(),e.enter().append("g").classed("edgeLabel",!0).style("opacity",0),e.each(function(t){var e=n.edge(t),a=i(u.select(this),n.edge(t),0,0).classed("label",!0),o=a.node().getBBox();e.labelId&&a.attr("id",e.labelId),r.has(e,"width")||(e.width=o.width),r.has(e,"height")||(e.height=o.height)}),a.applyTransition(e.exit(),n).style("opacity",0).remove(),e}var r=t("./lodash"),i=t("./label/add-label"),a=t("./util"),u=t("./d3");n.exports=e},{"./d3":9,"./label/add-label":20,"./lodash":23,"./util":29}],7:[function(t,n){"use strict";function e(t,n,e){var i=t.selectAll("g.edgePath").data(n.edges(),function(t){return l.edgeToId(t)}).classed("update",!0);return u(i,n),o(i,n),l.applyTransition(i,n).style("opacity",1),i.each(function(t){var e=h.select(this),r=n.edge(t);r.elem=this,r.id&&e.attr("id",r.id),l.applyClass(e,r["class"],(e.classed("update")?"update ":"")+"edgePath")}),i.selectAll("path.path").each(function(t){var e=n.edge(t);e.arrowheadId=s.uniqueId("arrowhead");var i=h.select(this).attr("marker-end",function(){return"url(#"+e.arrowheadId+")"}).style("fill","none");l.applyTransition(i,n).attr("d",function(t){return r(n,t)}),l.applyStyle(i,e.style)}),i.selectAll("defs *").remove(),i.selectAll("defs").each(function(t){var r=n.edge(t),i=e[r.arrowhead];i(h.select(this),r.arrowheadId,r,"arrowhead")}),i}function r(t,n){var e=t.edge(n),r=t.node(n.v),a=t.node(n.w),u=e.points.slice(1,e.points.length-1);return u.unshift(c(r,u[0])),u.push(c(a,u[u.length-1])),i(e,u)}function i(t,n){var e=h.svg.line().x(function(t){return t.x}).y(function(t){return t.y});return s.has(t,"lineInterpolate")&&e.interpolate(t.lineInterpolate),s.has(t,"lineTension")&&e.tension(Number(t.lineTension)),e(n)}function a(t){var n=t.getBBox(),e=t.getTransformToElement(t.ownerSVGElement).translate(n.width/2,n.height/2);return{x:e.e,y:e.f}}function u(t,n){var e=t.enter().append("g").attr("class","edgePath").style("opacity",0);e.append("path").attr("class","path").attr("d",function(t){var e=n.edge(t),r=n.node(t.v).elem,u=s.range(e.points.length).map(function(){return a(r)});return i(e,u)}),e.append("defs")}function o(t,n){var e=t.exit();l.applyTransition(e,n).style("opacity",0).remove(),l.applyTransition(e.select("path.path"),n).attr("d",function(t){var e=n.node(t.v);if(e){var r=s.range(this.pathSegList.length).map(function(){return e});return i({},r)}return h.select(this).attr("d")})}var s=t("./lodash"),c=t("./intersect/intersect-node"),l=t("./util"),h=t("./d3");n.exports=e},{"./d3":9,"./intersect/intersect-node":16,"./lodash":23,"./util":29}],8:[function(t,n){"use strict";function e(t,n,e){var o=n.nodes().filter(function(t){return!a.isSubgraph(n,t)}),s=t.selectAll("g.node").data(o,function(t){return t}).classed("update",!0);return s.selectAll("*").remove(),s.enter().append("g").attr("class","node").style("opacity",0),s.each(function(t){var o=n.node(t),s=u.select(this),c=s.append("g").attr("class","label"),l=i(c,o),h=e[o.shape],f=r.pick(l.node().getBBox(),"width","height");o.elem=this,o.id&&s.attr("id",o.id),o.labelId&&c.attr("id",o.labelId),a.applyClass(s,o["class"],(s.classed("update")?"update ":"")+"node"),r.has(o,"width")&&(f.width=o.width),r.has(o,"height")&&(f.height=o.height),f.width+=o.paddingLeft+o.paddingRight,f.height+=o.paddingTop+o.paddingBottom,c.attr("transform","translate("+(o.paddingLeft-o.paddingRight)/2+","+(o.paddingTop-o.paddingBottom)/2+")");var d=h(u.select(this),f,o);a.applyStyle(d,o.style);var p=d.node().getBBox();o.width=p.width,o.height=p.height}),a.applyTransition(s.exit(),n).style("opacity",0).remove(),s}var r=t("./lodash"),i=t("./label/add-label"),a=t("./util"),u=t("./d3");n.exports=e},{"./d3":9,"./label/add-label":20,"./lodash":23,"./util":29}],9:[function(t,n){n.exports=window.d3},{}],10:[function(t,n){var e;if(t)try{e=t("dagre")}catch(r){}e||(e=window.dagre),n.exports=e},{dagre:52}],11:[function(t,n){var e;if(t)try{e=t("graphlib")}catch(r){}e||(e=window.graphlib),n.exports=e},{graphlib:31}],12:[function(t,n){n.exports={node:t("./intersect-node"),circle:t("./intersect-circle"),ellipse:t("./intersect-ellipse"),polygon:t("./intersect-polygon"),rect:t("./intersect-rect")}},{"./intersect-circle":13,"./intersect-ellipse":14,"./intersect-node":16,"./intersect-polygon":17,"./intersect-rect":18}],13:[function(t,n){function e(t,n,e){return r(t,n,n,e)}var r=t("./intersect-ellipse");n.exports=e},{"./intersect-ellipse":14}],14:[function(t,n){function e(t,n,e,r){var i=t.x,a=t.y,u=i-r.x,o=a-r.y,s=Math.sqrt(n*n*o*o+e*e*u*u),c=Math.abs(n*e*u/s);r.xm?(m-y)/g:(m+y)/g,m=u*c-a*l,_=0>m?(m-y)/g:(m+y)/g,{x:v,y:_})}function r(t,n){return t*n>0}n.exports=e},{}],16:[function(t,n){function e(t,n){return t.intersect(n)}n.exports=e},{}],17:[function(t,n){function e(t,n,e){var i=t.x,a=t.y,u=[],o=Number.POSITIVE_INFINITY,s=Number.POSITIVE_INFINITY;n.forEach(function(t){o=Math.min(o,t.x),s=Math.min(s,t.y)});for(var c=i-t.width/2-o,l=a-t.height/2-s,h=0;h1&&u.sort(function(t,n){var r=t.x-e.x,i=t.y-e.y,a=Math.sqrt(r*r+i*i),u=n.x-e.x,o=n.y-e.y,s=Math.sqrt(u*u+o*o);return s>a?-1:a===s?0:1}),u[0]):(console.log("NO INTERSECTION FOUND, RETURN NODE CENTER",t),t)}var r=t("./intersect-line");n.exports=e},{"./intersect-line":15}],18:[function(t,n){ -function e(t,n){var e,r,i=t.x,a=t.y,u=n.x-i,o=n.y-a,s=t.width/2,c=t.height/2;return Math.abs(o)*s>Math.abs(u)*c?(0>o&&(c=-c),e=0===o?0:c*u/o,r=c):(0>u&&(s=-s),e=s,r=0===u?0:s*o/u),{x:i+e,y:a+r}}n.exports=e},{}],19:[function(t,n){function e(t,n){var e=t.append("foreignObject").attr("width","100000"),i=e.append("xhtml:div"),a=n.label;switch(typeof a){case"function":i.insert(a);break;case"object":i.insert(function(){return a});break;default:i.html(a)}r.applyStyle(i,n.labelStyle),i.style("display","inline-block"),i.style("white-space","nowrap");var u,o;return i.each(function(){u=this.clientWidth,o=this.clientHeight}),e.attr("width",u).attr("height",o),e}var r=t("../util");n.exports=e},{"../util":29}],20:[function(t,n){function e(t,n,e){var u=n.label,o=t.append("g");"svg"===n.labelType?a(o,n):"string"!=typeof u||"html"===n.labelType?i(o,n):r(o,n);var s,c=o.node().getBBox();switch(e){case"top":s=-n.height/2;break;case"bottom":s=n.height/2-c.height;break;default:s=-c.height/2}return o.attr("transform","translate("+-c.width/2+","+s+")"),o}var r=t("./add-text-label"),i=t("./add-html-label"),a=t("./add-svg-label");n.exports=e},{"./add-html-label":19,"./add-svg-label":21,"./add-text-label":22}],21:[function(t,n){function e(t,n){var e=t;return e.node().appendChild(n.label),r.applyStyle(e,n.labelStyle),e}var r=t("../util");n.exports=e},{"../util":29}],22:[function(t,n){function e(t,n){for(var e=t.append("text"),a=r(n.label).split("\n"),u=0;ua)throw new Error("dijkstra does not allow negative edge weights. Bad edge: "+t+" Weight: "+a);c0&&(i=s.removeMin(),u=o[i],u.distance!==Number.POSITIVE_INFINITY);)r(i).forEach(c);return o}var i=t("../lodash"),a=t("../data/priority-queue");n.exports=e;var u=i.constant(1)},{"../data/priority-queue":45,"../lodash":49}],36:[function(t,n){function e(t){return r.filter(i(t),function(n){return n.length>1||1===n.length&&t.hasEdge(n[0],n[0])})}var r=t("../lodash"),i=t("./tarjan");n.exports=e},{"../lodash":49,"./tarjan":43}],37:[function(t,n){function e(t,n,e){return r(t,n||a,e||function(n){return t.outEdges(n)})}function r(t,n,e){var r={},i=t.nodes();return i.forEach(function(t){r[t]={},r[t][t]={distance:0},i.forEach(function(n){t!==n&&(r[t][n]={distance:Number.POSITIVE_INFINITY})}),e(t).forEach(function(e){var i=e.v===t?e.w:e.v,a=n(e);r[t][i]={distance:a,predecessor:t}})}),i.forEach(function(t){var n=r[t];i.forEach(function(e){var a=r[e];i.forEach(function(e){var r=a[t],i=n[e],u=a[e],o=r.distance+i.distance;oi&&(s[e]=u,c.decrease(e,i))}}var u,o=new i,s={},c=new a;if(0===t.nodeCount())return o;r.each(t.nodes(),function(t){c.add(t,Number.POSITIVE_INFINITY),o.setNode(t)}),c.decrease(t.nodes()[0],0);for(var l=!1;c.size()>0;){if(u=c.removeMin(),r.has(s,u))o.setEdge(u,s[u]);else{if(l)throw new Error("Input graph is not connected: "+t);l=!0}t.nodeEdges(u).forEach(e)}return o}var r=t("../lodash"),i=t("../graph"),a=t("../data/priority-queue");n.exports=e},{"../data/priority-queue":45,"../graph":46,"../lodash":49}],43:[function(t,n){function e(t){function n(o){var s=a[o]={onStack:!0,lowlink:e,index:e++};if(i.push(o),t.successors(o).forEach(function(t){r.has(a,t)?a[t].onStack&&(s.lowlink=Math.min(s.lowlink,a[t].index)):(n(t),s.lowlink=Math.min(s.lowlink,a[t].lowlink))}),s.lowlink===s.index){var c,l=[];do c=i.pop(),a[c].onStack=!1,l.push(c);while(o!==c);u.push(l)}}var e=0,i=[],a={},u=[];return t.nodes().forEach(function(t){r.has(a,t)||n(t)}),u}var r=t("../lodash");n.exports=e},{"../lodash":49}],44:[function(t,n){function e(t){function n(o){if(i.has(a,o))throw new r;i.has(e,o)||(a[o]=!0,e[o]=!0,i.each(t.predecessors(o),n),delete a[o],u.push(o))}var e={},a={},u=[];if(i.each(t.sinks(),n),i.size(e)!==t.nodeCount())throw new r;return u}function r(){}var i=t("../lodash");n.exports=e,e.CycleException=r},{"../lodash":49}],45:[function(t,n){function e(){this._arr=[],this._keyIndices={}}var r=t("../lodash");n.exports=e,e.prototype.size=function(){return this._arr.length},e.prototype.keys=function(){return this._arr.map(function(t){return t.key})},e.prototype.has=function(t){return r.has(this._keyIndices,t)},e.prototype.priority=function(t){var n=this._keyIndices[t];return void 0!==n?this._arr[n].priority:void 0},e.prototype.min=function(){if(0===this.size())throw new Error("Queue underflow");return this._arr[0].key},e.prototype.add=function(t,n){var e=this._keyIndices;if(t=String(t),!r.has(e,t)){var i=this._arr,a=i.length;return e[t]=a,i.push({key:t,priority:n}),this._decrease(a),!0}return!1},e.prototype.removeMin=function(){this._swap(0,this._arr.length-1);var t=this._arr.pop();return delete this._keyIndices[t.key],this._heapify(0),t.key},e.prototype.decrease=function(t,n){var e=this._keyIndices[t];if(n>this._arr[e].priority)throw new Error("New priority is greater than current priority. Key: "+t+" Old: "+this._arr[e].priority+" New: "+n);this._arr[e].priority=n,this._decrease(e)},e.prototype._heapify=function(t){var n=this._arr,e=2*t,r=e+1,i=t;e>1,!(e[n].prioritya){var u=i;i=a,a=u}return i+h+a+h+(s.isUndefined(r)?c:r)}function u(t,n,e,r){var i=""+n,a=""+e;if(!t&&i>a){var u=i;i=a,a=u}var o={v:i,w:a};return r&&(o.name=r),o}function o(t,n){return a(t,n.v,n.w,n.name)}var s=t("./lodash");n.exports=e;var c="\x00",l="\x00",h="";e.prototype._nodeCount=0,e.prototype._edgeCount=0,e.prototype.isDirected=function(){return this._isDirected},e.prototype.isMultigraph=function(){return this._isMultigraph},e.prototype.isCompound=function(){return this._isCompound},e.prototype.setGraph=function(t){return this._label=t,this},e.prototype.graph=function(){return this._label},e.prototype.setDefaultNodeLabel=function(t){return s.isFunction(t)||(t=s.constant(t)),this._defaultNodeLabelFn=t,this},e.prototype.nodeCount=function(){return this._nodeCount},e.prototype.nodes=function(){return s.keys(this._nodes)},e.prototype.sources=function(){return s.filter(this.nodes(),function(t){return s.isEmpty(this._in[t])},this)},e.prototype.sinks=function(){return s.filter(this.nodes(),function(t){return s.isEmpty(this._out[t])},this)},e.prototype.setNodes=function(t,n){var e=arguments;return s.each(t,function(t){e.length>1?this.setNode(t,n):this.setNode(t)},this),this},e.prototype.setNode=function(t,n){return s.has(this._nodes,t)?(arguments.length>1&&(this._nodes[t]=n),this):(this._nodes[t]=arguments.length>1?n:this._defaultNodeLabelFn(t),this._isCompound&&(this._parent[t]=l,this._children[t]={},this._children[l][t]=!0),this._in[t]={},this._preds[t]={},this._out[t]={},this._sucs[t]={},++this._nodeCount,this)},e.prototype.node=function(t){return this._nodes[t]},e.prototype.hasNode=function(t){return s.has(this._nodes,t)},e.prototype.removeNode=function(t){var n=this;if(s.has(this._nodes,t)){var e=function(t){n.removeEdge(n._edgeObjs[t])};delete this._nodes[t],this._isCompound&&(this._removeFromParentsChildList(t),delete this._parent[t],s.each(this.children(t),function(t){this.setParent(t)},this),delete this._children[t]),s.each(s.keys(this._in[t]),e),delete this._in[t],delete this._preds[t],s.each(s.keys(this._out[t]),e),delete this._out[t],delete this._sucs[t],--this._nodeCount}return this},e.prototype.setParent=function(t,n){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(s.isUndefined(n))n=l;else{n+="";for(var e=n;!s.isUndefined(e);e=this.parent(e))if(e===t)throw new Error("Setting "+n+" as parent of "+t+" would create create a cycle");this.setNode(n)}return this.setNode(t),this._removeFromParentsChildList(t),this._parent[t]=n,this._children[n][t]=!0,this},e.prototype._removeFromParentsChildList=function(t){delete this._children[this._parent[t]][t]},e.prototype.parent=function(t){if(this._isCompound){var n=this._parent[t];if(n!==l)return n}},e.prototype.children=function(t){if(s.isUndefined(t)&&(t=l),this._isCompound){var n=this._children[t];if(n)return s.keys(n)}else{if(t===l)return this.nodes();if(this.hasNode(t))return[]}},e.prototype.predecessors=function(t){var n=this._preds[t];return n?s.keys(n):void 0},e.prototype.successors=function(t){var n=this._sucs[t];return n?s.keys(n):void 0},e.prototype.neighbors=function(t){var n=this.predecessors(t);return n?s.union(n,this.successors(t)):void 0},e.prototype.filterNodes=function(t){function n(t){var a=r.parent(t);return void 0===a||e.hasNode(a)?(i[t]=a,a):a in i?i[a]:n(a)}var e=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});e.setGraph(this.graph()),s.each(this._nodes,function(n,r){t(r)&&e.setNode(r,n)},this),s.each(this._edgeObjs,function(t){e.hasNode(t.v)&&e.hasNode(t.w)&&e.setEdge(t,this.edge(t))},this);var r=this,i={};return this._isCompound&&s.each(e.nodes(),function(t){e.setParent(t,n(t))}),e},e.prototype.setDefaultEdgeLabel=function(t){return s.isFunction(t)||(t=s.constant(t)),this._defaultEdgeLabelFn=t,this},e.prototype.edgeCount=function(){return this._edgeCount},e.prototype.edges=function(){return s.values(this._edgeObjs)},e.prototype.setPath=function(t,n){var e=this,r=arguments;return s.reduce(t,function(t,i){return r.length>1?e.setEdge(t,i,n):e.setEdge(t,i),i}),this},e.prototype.setEdge=function(){var t,n,e,i,o=!1,c=arguments[0];"object"==typeof c&&null!==c&&"v"in c?(t=c.v,n=c.w,e=c.name,2===arguments.length&&(i=arguments[1],o=!0)):(t=c,n=arguments[1],e=arguments[3],arguments.length>2&&(i=arguments[2],o=!0)),t=""+t,n=""+n,s.isUndefined(e)||(e=""+e);var l=a(this._isDirected,t,n,e);if(s.has(this._edgeLabels,l))return o&&(this._edgeLabels[l]=i),this;if(!s.isUndefined(e)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(t),this.setNode(n),this._edgeLabels[l]=o?i:this._defaultEdgeLabelFn(t,n,e);var h=u(this._isDirected,t,n,e);return t=h.v,n=h.w,Object.freeze(h),this._edgeObjs[l]=h,r(this._preds[n],t),r(this._sucs[t],n),this._in[n][l]=h,this._out[t][l]=h,this._edgeCount++,this},e.prototype.edge=function(t,n,e){var r=1===arguments.length?o(this._isDirected,arguments[0]):a(this._isDirected,t,n,e);return this._edgeLabels[r]},e.prototype.hasEdge=function(t,n,e){var r=1===arguments.length?o(this._isDirected,arguments[0]):a(this._isDirected,t,n,e);return s.has(this._edgeLabels,r)},e.prototype.removeEdge=function(t,n,e){var r=1===arguments.length?o(this._isDirected,arguments[0]):a(this._isDirected,t,n,e),u=this._edgeObjs[r];return u&&(t=u.v,n=u.w,delete this._edgeLabels[r],delete this._edgeObjs[r],i(this._preds[n],t),i(this._sucs[t],n),delete this._in[n][r],delete this._out[t][r],this._edgeCount--),this},e.prototype.inEdges=function(t,n){var e=this._in[t];if(e){var r=s.values(e);return n?s.filter(r,function(t){return t.v===n}):r}},e.prototype.outEdges=function(t,n){var e=this._out[t];if(e){var r=s.values(e);return n?s.filter(r,function(t){return t.w===n}):r}},e.prototype.nodeEdges=function(t,n){var e=this.inEdges(t,n);return e?e.concat(this.outEdges(t,n)):void 0}},{"./lodash":49}],47:[function(t,n){n.exports={Graph:t("./graph"),version:t("./version")}},{"./graph":46,"./version":50}],48:[function(t,n){function e(t){var n={options:{directed:t.isDirected(),multigraph:t.isMultigraph(),compound:t.isCompound()},nodes:r(t),edges:i(t)};return u.isUndefined(t.graph())||(n.value=u.clone(t.graph())),n}function r(t){return u.map(t.nodes(),function(n){var e=t.node(n),r=t.parent(n),i={v:n};return u.isUndefined(e)||(i.value=e),u.isUndefined(r)||(i.parent=r),i})}function i(t){return u.map(t.edges(),function(n){var e=t.edge(n),r={v:n.v,w:n.w};return u.isUndefined(n.name)||(r.name=n.name),u.isUndefined(e)||(r.value=e),r})}function a(t){var n=new o(t.options).setGraph(t.value);return u.each(t.nodes,function(t){n.setNode(t.v,t.value),t.parent&&n.setParent(t.v,t.parent)}),u.each(t.edges,function(t){n.setEdge({v:t.v,w:t.w,name:t.name},t.value)}),n}var u=t("./lodash"),o=t("./graph");n.exports={write:e,read:a}},{"./graph":46,"./lodash":49}],49:[function(t,n){var e;if("function"==typeof t)try{e=t("lodash")}catch(r){}e||(e=window._),n.exports=e},{lodash:51}],50:[function(t,n){n.exports="1.0.7"},{}],51:[function(t,n,e){(function(t){(function(){function r(t,n){if(t!==n){var e=null===t,r=t===E,i=t===t,a=null===n,u=n===E,o=n===n;if(t>n&&!a||!i||e&&!u&&o||r&&o)return 1;if(n>t&&!e||!o||a&&!r&&i||u&&i)return-1}return 0}function i(t,n,e){for(var r=t.length,i=e?r:-1;e?i--:++i-1;);return e}function c(t,n){for(var e=t.length;e--&&n.indexOf(t.charAt(e))>-1;);return e}function l(t,n){return r(t.criteria,n.criteria)||t.index-n.index}function h(t,n,e){for(var i=-1,a=t.criteria,u=n.criteria,o=a.length,s=e.length;++i=s)return c;var l=e[i];return c*("asc"===l||l===!0?1:-1)}}return t.index-n.index}function f(t){return zt[t]}function d(t){return qt[t]}function p(t,n,e){return n?t=Vt[t]:e&&(t=Zt[t]),"\\"+t}function g(t){return"\\"+Zt[t]}function y(t,n,e){for(var r=t.length,i=n+(e?0:-1);e?i--:++i=t&&t>=9&&13>=t||32==t||160==t||5760==t||6158==t||t>=8192&&(8202>=t||8232==t||8233==t||8239==t||8287==t||12288==t||65279==t)}function _(t,n){for(var e=-1,r=t.length,i=-1,a=[];++en,i=e?t.length:0,a=Ge(0,i,this.__views__),u=a.start,o=a.end,s=o-u,c=r?o:u-1,l=this.__iteratees__,h=l.length,f=0,d=wu(s,this.__takeCount__);if(!e||Y>i||i==s&&d==s)return re(r&&e?t.reverse():t,this.__actions__);var p=[];t:for(;s--&&d>f;){c+=n;for(var g=-1,y=t[c];++g=Y?ge(n):null,c=n.length;s&&(u=Kt,o=!1,n=s);t:for(;++ie&&(e=-e>i?0:i+e),r=r===E||r>i?i:+r||0,0>r&&(r+=i),i=e>r?0:r>>>0,e>>>=0;i>e;)t[e++]=n;return t}function Dn(t,n){var e=[];return Bu(t,function(t,r,i){n(t,r,i)&&e.push(t)}),e}function Cn(t,n,e,r){var i;return e(t,function(t,e,a){return n(t,e,a)?(i=r?e:t,!1):void 0}),i}function Tn(t,n,e,r){r||(r=[]);for(var i=-1,a=t.length;++ir;)t=t[n[r++]];return r&&r==i?t:E}}function Nn(t,n,e,r,i,a){return t===n?!0:null==t||null==n||!Ii(t)&&!m(n)?t!==t&&n!==n:Pn(t,n,Nn,e,r,i,a)}function Pn(t,n,e,r,i,a,u){var o=Co(t),s=Co(n),c=G,l=G;o||(c=eu.call(t),c==q?c=J:c!=J&&(o=Wi(t))),s||(l=eu.call(n),l==q?l=J:l!=J&&(s=Wi(n)));var h=c==J,f=l==J,d=c==l;if(d&&!o&&!h)return je(t,n,c);if(!i){var p=h&&tu.call(t,"__wrapped__"),g=f&&tu.call(n,"__wrapped__");if(p||g)return e(p?t.value():t,g?n.value():n,r,i,a,u)}if(!d)return!1;a||(a=[]),u||(u=[]);for(var y=a.length;y--;)if(a[y]==t)return u[y]==n;a.push(t),u.push(n);var m=(o?Re:Ye)(t,n,e,r,i,a,u);return a.pop(),u.pop(),m}function Rn(t,n,e){var r=n.length,i=r,a=!e;if(null==t)return!i;for(t=hr(t);r--;){var u=n[r];if(a&&u[2]?u[1]!==t[u[0]]:!(u[0]in t))return!1}for(;++rn&&(n=-n>i?0:i+n),e=e===E||e>i?i:+e||0,0>e&&(e+=i),i=n>e?0:e-n>>>0,n>>>=0;for(var a=Ya(i);++r=Y,s=o?ge():null,c=[];s?(r=Kt,u=!1):(o=!1,s=n?[]:c);t:for(;++e=i){for(;i>r;){ -var a=r+i>>>1,u=t[a];(e?n>=u:n>u)&&null!==u?r=a+1:i=a}return i}return ae(t,n,Sa,e)}function ae(t,n,e,r){n=e(n);for(var i=0,a=t?t.length:0,u=n!==n,o=null===n,s=n===E;a>i;){var c=mu((i+a)/2),l=e(t[c]),h=l!==E,f=l===l;if(u)var d=f||r;else d=o?f&&h&&(r||null!=l):s?f&&(r||h):null==l?!1:r?n>=l:n>l;d?i=c+1:a=c}return wu(a,Cu)}function ue(t,n,e){if("function"!=typeof t)return Sa;if(n===E)return t;switch(e){case 1:return function(e){return t.call(n,e)};case 3:return function(e,r,i){return t.call(n,e,r,i)};case 4:return function(e,r,i,a){return t.call(n,e,r,i,a)};case 5:return function(e,r,i,a,u){return t.call(n,e,r,i,a,u)}}return function(){return t.apply(n,arguments)}}function oe(t){var n=new au(t.byteLength),e=new du(n);return e.set(new du(t)),n}function se(t,n,e){for(var r=e.length,i=-1,a=xu(t.length-r,0),u=-1,o=n.length,s=Ya(o+a);++u2?e[i-2]:E,u=i>2?e[2]:E,o=i>1?e[i-1]:E;for("function"==typeof a?(a=ue(a,o,5),i-=2):(a="function"==typeof o?o:E,i-=a?1:0),u&&Je(e[0],e[1],u)&&(a=3>i?E:a,i=1);++r-1?e[u]:E}return Cn(e,r,t)}}function we(t){return function(n,e,r){return n&&n.length?(e=Ue(e,r,3),i(n,e,t)):-1}}function Ae(t){return function(n,e,r){return e=Ue(e,r,3),Cn(n,e,t,!0)}}function ke(t){return function(){for(var n,e=arguments.length,r=t?e:-1,i=0,a=Ya(e);t?r--:++r=Y)return n.plant(r).value();for(var i=0,u=e?a[i].apply(this,t):r;++iv){var k=o?tn(o):E,M=xu(c-v,0),C=p?A:E,T=p?E:A,F=p?x:E,I=p?E:x;n|=p?O:L,n&=~(p?L:O),g||(n&=~(S|D));var B=[t,n,e,F,C,I,T,k,s,M],N=Oe.apply(E,B);return nr(t)&&$u(N,B),N.placeholder=w,N}}var P=f?e:this,R=d?P[t]:t;return o&&(x=sr(x,o)),h&&s=n||!_u(n))return"";var i=n-r;return e=null==e?" ":e+"",ya(e,gu(i/e.length)).slice(0,i)}function Ie(t,n,e,r){function i(){for(var n=-1,o=arguments.length,s=-1,c=r.length,l=Ya(c+o);++ss))return!1;for(;++o-1&&t%1==0&&n>t}function Je(t,n,e){if(!Ii(e))return!1;var r=typeof n;if("number"==r?Ke(e)&&Qe(n,e.length):"string"==r&&n in e){var i=e[n];return t===t?t===i:i!==i}return!1}function tr(t,n){var e=typeof t;if("string"==e&&Et.test(t)||"number"==e)return!0;if(Co(t))return!1;var r=!kt.test(t);return r||null!=n&&t in hr(n)}function nr(t){var e=$e(t);if(!(e in K.prototype))return!1;var r=n[e];if(t===r)return!0;var i=Yu(r);return!!i&&t===i[0]}function er(t){return"number"==typeof t&&t>-1&&t%1==0&&Fu>=t}function rr(t){return t===t&&!Ii(t)}function ir(t,n){var e=t[1],r=n[1],i=e|r,a=I>i,u=r==I&&e==T||r==I&&e==B&&t[7].length<=n[8]||r==(I|B)&&e==T;if(!a&&!u)return t;r&S&&(t[2]=n[2],i|=e&S?0:C);var o=n[3];if(o){var s=t[3];t[3]=s?se(s,o,n[4]):tn(o),t[4]=s?_(t[3],z):tn(n[4])}return o=n[5],o&&(s=t[5],t[5]=s?ce(s,o,n[6]):tn(o),t[6]=s?_(t[5],z):tn(n[6])),o=n[7],o&&(t[7]=tn(o)),r&I&&(t[8]=null==t[8]?n[8]:wu(t[8],n[8])),null==t[9]&&(t[9]=n[9]),t[0]=n[0],t[1]=i,t}function ar(t,n){return t===E?n:To(t,n,ar)}function ur(t,n){t=hr(t);for(var e=-1,r=n.length,i={};++er;)u[++a]=Zn(t,r,r+=n);return u}function gr(t){for(var n=-1,e=t?t.length:0,r=-1,i=[];++nn?0:n)):[]}function mr(t,n,e){var r=t?t.length:0;return r?((e?Je(t,n,e):null==n)&&(n=1),n=r-(+n||0),Zn(t,0,0>n?0:n)):[]}function vr(t,n,e){return t&&t.length?ee(t,Ue(n,e,3),!0,!0):[]}function _r(t,n,e){return t&&t.length?ee(t,Ue(n,e,3),!0):[]}function br(t,n,e,r){var i=t?t.length:0;return i?(e&&"number"!=typeof e&&Je(t,n,e)&&(e=0,r=i),Sn(t,n,e,r)):[]}function xr(t){return t?t[0]:E}function wr(t,n,e){var r=t?t.length:0;return e&&Je(t,n,e)&&(n=!1),r?Tn(t,n):[]}function Ar(t){var n=t?t.length:0;return n?Tn(t,!0):[]}function kr(t,n,e){var r=t?t.length:0;if(!r)return-1;if("number"==typeof e)e=0>e?xu(r+e,0):e;else if(e){var i=ie(t,n);return r>i&&(n===n?n===t[i]:t[i]!==t[i])?i:-1}return a(t,n,e||0)}function Er(t){return mr(t,1)}function Mr(t){var n=t?t.length:0;return n?t[n-1]:E}function Sr(t,n,e){var r=t?t.length:0;if(!r)return-1;var i=r;if("number"==typeof e)i=(0>e?xu(r+e,0):wu(e||0,r-1))+1;else if(e){i=ie(t,n,!0)-1;var a=t[i];return(n===n?n===a:a!==a)?i:-1}if(n!==n)return y(t,i,!0);for(;i--;)if(t[i]===n)return i;return-1}function Dr(){var t=arguments,n=t[0];if(!n||!n.length)return n;for(var e=0,r=We(),i=t.length;++e-1;)fu.call(n,a,1);return n}function Cr(t,n,e){var r=[];if(!t||!t.length)return r;var i=-1,a=[],u=t.length;for(n=Ue(n,e,3);++in?0:n)):[]}function Lr(t,n,e){var r=t?t.length:0;return r?((e?Je(t,n,e):null==n)&&(n=1),n=r-(+n||0),Zn(t,0>n?0:n)):[]}function Ir(t,n,e){return t&&t.length?ee(t,Ue(n,e,3),!1,!0):[]}function Br(t,n,e){return t&&t.length?ee(t,Ue(n,e,3)):[]}function Nr(t,n,e,r){var i=t?t.length:0;if(!i)return[];null!=n&&"boolean"!=typeof n&&(r=e,e=Je(t,n,r)?E:n,n=!1);var u=Ue();return(null!=e||u!==xn)&&(e=u(e,r,3)),n&&We()==a?b(t,e):te(t,e)}function Pr(t){if(!t||!t.length)return[];var n=-1,e=0;t=sn(t,function(t){return Ke(t)?(e=xu(t.length,e),!0):void 0});for(var r=Ya(e);++ne?xu(i+e,0):e||0,"string"==typeof t||!Co(t)&&$i(t)?i>=e&&t.indexOf(n,e)>-1:!!i&&We(t,n,e)>-1}function ti(t,n,e){var r=Co(t)?cn:jn;return n=Ue(n,e,3),r(t,n)}function ni(t,n){return ti(t,La(n))}function ei(t,n,e){var r=Co(t)?sn:Dn;return n=Ue(n,e,3),r(t,function(t,e,r){return!n(t,e,r)})}function ri(t,n,e){if(e?Je(t,n,e):null==n){t=lr(t);var r=t.length;return r>0?t[Hn(0,r-1)]:E}var i=-1,a=Hi(t),r=a.length,u=r-1;for(n=wu(0>n?0:+n||0,r);++i0&&(e=n.apply(this,arguments)),1>=t&&(n=E),e}}function di(t,n,e){function r(){d&&uu(d),c&&uu(c),g=0,c=d=p=E}function i(n,e){e&&uu(e),c=d=p=E,n&&(g=go(),l=t.apply(f,s),d||c||(s=f=E))}function a(){var t=n-(go()-h);0>=t||t>n?i(p,c):d=hu(a,t)}function u(){i(m,d)}function o(){if(s=arguments,h=go(),f=this,p=m&&(d||!v),y===!1)var e=v&&!d;else{c||v||(g=h);var r=y-(h-g),i=0>=r||r>y;i?(c&&(c=uu(c)),g=h,l=t.apply(f,s)):c||(c=hu(u,r))}return i&&d?d=uu(d):d||n===y||(d=hu(a,n)),e&&(i=!0,l=t.apply(f,s)),!i||d||c||(s=f=E),l}var s,c,l,h,f,d,p,g=0,y=!1,m=!0;if("function"!=typeof t)throw new Za(W);if(n=0>n?0:+n||0,e===!0){var v=!0;m=!1}else Ii(e)&&(v=!!e.leading,y="maxWait"in e&&xu(+e.maxWait||0,n),m="trailing"in e?!!e.trailing:m);return o.cancel=r,o}function pi(t,n){if("function"!=typeof t||n&&"function"!=typeof n)throw new Za(W);var e=function(){var r=arguments,i=n?n.apply(this,r):r[0],a=e.cache;if(a.has(i))return a.get(i);var u=t.apply(this,r);return e.cache=a.set(i,u),u};return e.cache=new pi.Cache,e}function gi(t){if("function"!=typeof t)throw new Za(W);return function(){return!t.apply(this,arguments)}}function yi(t){return fi(2,t)}function mi(t,n){if("function"!=typeof t)throw new Za(W);return n=xu(n===E?t.length-1:+n||0,0),function(){for(var e=arguments,r=-1,i=xu(e.length-n,0),a=Ya(i);++rn}function ki(t,n){return t>=n}function Ei(t){return m(t)&&Ke(t)&&tu.call(t,"callee")&&!cu.call(t,"callee")}function Mi(t){return t===!0||t===!1||m(t)&&eu.call(t)==H}function Si(t){return m(t)&&eu.call(t)==V}function Di(t){return!!t&&1===t.nodeType&&m(t)&&!Yi(t)}function Ci(t){return null==t?!0:Ke(t)&&(Co(t)||$i(t)||Ei(t)||m(t)&&Li(t.splice))?!t.length:!Yo(t).length}function Ti(t,n,e,r){e="function"==typeof e?ue(e,r,3):E;var i=e?e(t,n):E;return i===E?Nn(t,n,e):!!i}function Fi(t){return m(t)&&"string"==typeof t.message&&eu.call(t)==Z}function Oi(t){return"number"==typeof t&&_u(t)}function Li(t){return Ii(t)&&eu.call(t)==X}function Ii(t){var n=typeof t;return!!t&&("object"==n||"function"==n)}function Bi(t,n,e,r){return e="function"==typeof e?ue(e,r,3):E,Rn(t,ze(n),e)}function Ni(t){return ji(t)&&t!=+t}function Pi(t){return null==t?!1:Li(t)?iu.test(Ja.call(t)):m(t)&&It.test(t)}function Ri(t){return null===t}function ji(t){return"number"==typeof t||m(t)&&eu.call(t)==Q}function Yi(t){var n;if(!m(t)||eu.call(t)!=J||Ei(t)||!tu.call(t,"constructor")&&(n=t.constructor,"function"==typeof n&&!(n instanceof n)))return!1;var e;return Fn(t,function(t,n){e=n}),e===E||tu.call(t,e)}function Ui(t){return Ii(t)&&eu.call(t)==tt}function $i(t){return"string"==typeof t||m(t)&&eu.call(t)==et}function Wi(t){return m(t)&&er(t.length)&&!!$t[eu.call(t)]}function zi(t){return t===E}function qi(t,n){return n>t}function Gi(t,n){return n>=t}function Hi(t){var n=t?Uu(t):0;return er(n)?n?tn(t):[]:aa(t)}function Vi(t){return bn(t,ta(t))}function Zi(t,n,e){var r=Iu(t);return e&&Je(t,n,e)&&(n=E),n?vn(r,n):r}function Xi(t){return In(t,ta(t))}function Ki(t,n,e){var r=null==t?E:Bn(t,fr(n),n+"");return r===E?e:r}function Qi(t,n){if(null==t)return!1;var e=tu.call(t,n);if(!e&&!tr(n)){if(n=fr(n),t=1==n.length?t:Bn(t,Zn(n,0,-1)),null==t)return!1;n=Mr(n),e=tu.call(t,n)}return e||er(t.length)&&Qe(n,t.length)&&(Co(t)||Ei(t))}function Ji(t,n,e){e&&Je(t,n,e)&&(n=E);for(var r=-1,i=Yo(t),a=i.length,u={};++r0;++r=wu(n,e)&&te?0:+e||0,r),e-=n.length,e>=0&&t.indexOf(n,e)==e}function fa(t){return t=o(t),t&&bt.test(t)?t.replace(vt,d):t}function da(t){return t=o(t),t&&Dt.test(t)?t.replace(St,p):t||"(?:)"}function pa(t,n,e){t=o(t),n=+n;var r=t.length;if(r>=n||!_u(n))return t;var i=(n-r)/2,a=mu(i),u=gu(i);return e=Le("",u,e),e.slice(0,a)+t+e}function ga(t,n,e){return(e?Je(t,n,e):null==n)?n=0:n&&(n=+n),t=_a(t),ku(t,n||(Lt.test(t)?16:10))}function ya(t,n){var e="";if(t=o(t),n=+n,1>n||!t||!_u(n))return e;do n%2&&(e+=t),n=mu(n/2),t+=t;while(n);return e}function ma(t,n,e){return t=o(t),e=null==e?0:wu(0>e?0:+e||0,t.length),t.lastIndexOf(n,e)==e}function va(t,e,r){var i=n.templateSettings;r&&Je(t,e,r)&&(e=r=E),t=o(t),e=mn(vn({},r||e),i,yn);var a,u,s=mn(vn({},e.imports),i.imports,yn),c=Yo(s),l=ne(s,c),h=0,f=e.interpolate||Pt,d="__p += '",p=Ha((e.escape||Pt).source+"|"+f.source+"|"+(f===At?Ft:Pt).source+"|"+(e.evaluate||Pt).source+"|$","g"),y="//# sourceURL="+("sourceURL"in e?e.sourceURL:"lodash.templateSources["+ ++Ut+"]")+"\n";t.replace(p,function(n,e,r,i,o,s){return r||(r=i),d+=t.slice(h,s).replace(Rt,g),e&&(a=!0,d+="' +\n__e("+e+") +\n'"),o&&(u=!0,d+="';\n"+o+";\n__p += '"),r&&(d+="' +\n((__t = ("+r+")) == null ? '' : __t) +\n'"),h=s+n.length,n}),d+="';\n";var m=e.variable;m||(d="with (obj) {\n"+d+"\n}\n"),d=(u?d.replace(pt,""):d).replace(gt,"$1").replace(yt,"$1;"),d="function("+(m||"obj")+") {\n"+(m?"":"obj || (obj = {});\n")+"var __t, __p = ''"+(a?", __e = _.escape":"")+(u?", __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\n":";\n")+d+"return __p\n}";var v=Ko(function(){return Wa(c,y+"return "+d).apply(E,l)});if(v.source=d,Fi(v))throw v;return v}function _a(t,n,e){var r=t;return(t=o(t))?(e?Je(r,n,e):null==n)?t.slice(x(t),w(t)+1):(n+="",t.slice(s(t,n),c(t,n)+1)):t}function ba(t,n,e){var r=t;return t=o(t),t?t.slice((e?Je(r,n,e):null==n)?x(t):s(t,n+"")):t}function xa(t,n,e){var r=t;return t=o(t),t?(e?Je(r,n,e):null==n)?t.slice(0,w(t)+1):t.slice(0,c(t,n+"")+1):t}function wa(t,n,e){e&&Je(t,n,e)&&(n=E);var r=N,i=P;if(null!=n)if(Ii(n)){var a="separator"in n?n.separator:a;r="length"in n?+n.length||0:r,i="omission"in n?o(n.omission):i}else r=+n||0;if(t=o(t),r>=t.length)return t;var u=r-i.length;if(1>u)return i;var s=t.slice(0,u);if(null==a)return s+i;if(Ui(a)){if(t.slice(u).search(a)){var c,l,h=t.slice(0,u);for(a.global||(a=Ha(a.source,(Ot.exec(a)||"")+"g")),a.lastIndex=0;c=a.exec(h);)l=c.index;s=s.slice(0,null==l?u:l)}}else if(t.indexOf(a,u)!=u){var f=s.lastIndexOf(a);f>-1&&(s=s.slice(0,f))}return s+i}function Aa(t){return t=o(t),t&&_t.test(t)?t.replace(mt,A):t}function ka(t,n,e){return e&&Je(t,n,e)&&(n=E),t=o(t),t.match(n||jt)||[]}function Ea(t,n,e){return e&&Je(t,n,e)&&(n=E),m(t)?Da(t):xn(t,n)}function Ma(t){return function(){return t}}function Sa(t){return t}function Da(t){return Yn(wn(t,!0))}function Ca(t,n){return Un(t,wn(n,!0))}function Ta(t,n,e){if(null==e){var r=Ii(n),i=r?Yo(n):E,a=i&&i.length?In(n,i):E;(a?a.length:r)||(a=!1,e=n,n=t,t=this)}a||(a=In(n,Yo(n)));var u=!0,o=-1,s=Li(t),c=a.length;e===!1?u=!1:Ii(e)&&"chain"in e&&(u=e.chain);for(;++ot||!_u(t))return[];var r=-1,i=Ya(wu(t,Du));for(n=ue(n,e,1);++rr?i[r]=n(r):n(r);return i}function Pa(t){var n=++nu;return o(t)+n}function Ra(t,n){return(+t||0)+(+n||0)}function ja(t,n,e){return e&&Je(t,n,e)&&(n=E),n=Ue(n,e,3),1==n.length?pn(Co(t)?t:lr(t),n):Jn(t,n)}t=t?rn.defaults(en.Object(),t,rn.pick(en,Yt)):en;{var Ya=t.Array,Ua=t.Date,$a=t.Error,Wa=t.Function,za=t.Math,qa=t.Number,Ga=t.Object,Ha=t.RegExp,Va=t.String,Za=t.TypeError,Xa=Ya.prototype,Ka=Ga.prototype,Qa=Va.prototype,Ja=Wa.prototype.toString,tu=Ka.hasOwnProperty,nu=0,eu=Ka.toString,ru=en._,iu=Ha("^"+Ja.call(tu).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),au=t.ArrayBuffer,uu=t.clearTimeout,ou=t.parseFloat,su=za.pow,cu=Ka.propertyIsEnumerable,lu=qe(t,"Set"),hu=t.setTimeout,fu=Xa.splice,du=t.Uint8Array,pu=qe(t,"WeakMap"),gu=za.ceil,yu=qe(Ga,"create"),mu=za.floor,vu=qe(Ya,"isArray"),_u=t.isFinite,bu=qe(Ga,"keys"),xu=za.max,wu=za.min,Au=qe(Ua,"now"),ku=t.parseInt,Eu=za.random,Mu=qa.NEGATIVE_INFINITY,Su=qa.POSITIVE_INFINITY,Du=4294967295,Cu=Du-1,Tu=Du>>>1,Fu=9007199254740991,Ou=pu&&new pu,Lu={};n.support={}}n.templateSettings={escape:xt,evaluate:wt,interpolate:At,variable:"",imports:{_:n}};var Iu=function(){function t(){}return function(n){if(Ii(n)){t.prototype=n;var e=new t;t.prototype=E}return e||{}}}(),Bu=fe(On),Nu=fe(Ln,!0),Pu=de(),Ru=de(!0),ju=Ou?function(t,n){return Ou.set(t,n),t}:Sa,Yu=Ou?function(t){return Ou.get(t)}:Oa,Uu=zn("length"),$u=function(){var t=0,n=0;return function(e,r){var i=go(),a=j-(i-n);if(n=i,a>0){if(++t>=R)return e}else t=0;return ju(e,r)}}(),Wu=mi(function(t,n){return m(t)&&Ke(t)?kn(t,Tn(n,!1,!0)):[]}),zu=we(),qu=we(!0),Gu=mi(function(t){for(var n=t.length,e=n,r=Ya(h),i=We(),u=i==a,o=[];e--;){var s=t[e]=Ke(s=t[e])?s:[];r[e]=u&&s.length>=120?ge(e&&s):null}var c=t[0],l=-1,h=c?c.length:0,f=r[0];t:for(;++l2?t[n-2]:E,r=n>1?t[n-1]:E;return n>2&&"function"==typeof e?n-=2:(e=n>1&&"function"==typeof r?(--n,r):E,r=E),t.length=n,Rr(t,e,r)}),to=mi(function(t){return t=Tn(t),this.thru(function(n){return Jt(Co(n)?n:[hr(n)],t)})}),no=mi(function(t,n){return _n(t,Tn(n))}),eo=le(function(t,n,e){tu.call(t,e)?++t[e]:t[e]=1}),ro=xe(Bu),io=xe(Nu,!0),ao=Ee(nn,Bu),uo=Ee(an,Nu),oo=le(function(t,n,e){tu.call(t,e)?t[e].push(n):t[e]=[n]}),so=le(function(t,n,e){t[e]=n}),co=mi(function(t,n,e){var r=-1,i="function"==typeof n,a=tr(n),u=Ke(t)?Ya(t.length):[];return Bu(t,function(t){var o=i?n:a&&null!=t?t[n]:E;u[++r]=o?o.apply(t,e):Xe(t,n,e)}),u}),lo=le(function(t,n,e){t[e?0:1].push(n)},function(){return[[],[]]}),ho=Fe(hn,Bu),fo=Fe(fn,Nu),po=mi(function(t,n){if(null==t)return[];var e=n[2];return e&&Je(n[0],n[1],e)&&(n.length=1),Qn(t,Tn(n),[])}),go=Au||function(){return(new Ua).getTime()},yo=mi(function(t,n,e){var r=S;if(e.length){var i=_(e,yo.placeholder);r|=O}return Pe(t,r,n,e,i)}),mo=mi(function(t,n){n=n.length?Tn(n):Xi(t);for(var e=-1,r=n.length;++e0||0>n)?new K(e):(0>t?e=e.takeRight(-t):t&&(e=e.drop(t)),n!==E&&(n=+n||0,e=0>n?e.dropRight(-n):e.take(n-t)),e)},K.prototype.takeRightWhile=function(t,n){return this.reverse().takeWhile(t,n).reverse()},K.prototype.toArray=function(){return this.take(Su)},On(K.prototype,function(t,e){var r=/^(?:filter|map|reject)|While$/.test(e),i=/^(?:first|last)$/.test(e),a=n[i?"take"+("last"==e?"Right":""):e];a&&(n.prototype[e]=function(){var n=i?[1]:arguments,e=this.__chain__,u=this.__wrapped__,o=!!this.__actions__.length,s=u instanceof K,c=n[0],l=s||Co(u);l&&r&&"function"==typeof c&&1!=c.length&&(s=l=!1);var h=function(t){return i&&e?a(t,1)[0]:a.apply(E,ln([t],n))},f={func:Wr,args:[h],thisArg:E},d=s&&!o;if(i&&!e)return d?(u=u.clone(),u.__actions__.push(f),t.call(u)):a.call(E,this.value())[0];if(!i&&l){u=d?u:new K(this);var p=t.apply(u,n);return p.__actions__.push(f),new v(p,e)}return this.thru(h)})}),nn(["join","pop","push","replace","shift","sort","splice","split","unshift"],function(t){var e=(/^(?:replace|split)$/.test(t)?Qa:Xa)[t],r=/^(?:push|sort|unshift)$/.test(t)?"tap":"thru",i=/^(?:join|pop|replace|shift)$/.test(t);n.prototype[t]=function(){var t=arguments;return i&&!this.__chain__?e.apply(this.value(),t):this[r](function(n){return e.apply(n,t)})}}),On(K.prototype,function(t,e){var r=n[e];if(r){var i=r.name,a=Lu[i]||(Lu[i]=[]);a.push({name:e,func:r})}}),Lu[Oe(E,D).name]=[{name:"wrapper",func:E}],K.prototype.clone=nt,K.prototype.reverse=rt,K.prototype.value=zt,n.prototype.chain=zr,n.prototype.commit=qr,n.prototype.concat=to,n.prototype.plant=Gr,n.prototype.reverse=Hr,n.prototype.toString=Vr,n.prototype.run=n.prototype.toJSON=n.prototype.valueOf=n.prototype.value=Zr,n.prototype.collect=n.prototype.map,n.prototype.head=n.prototype.first,n.prototype.select=n.prototype.filter,n.prototype.tail=n.prototype.rest,n}var E,M="3.10.1",S=1,D=2,C=4,T=8,F=16,O=32,L=64,I=128,B=256,N=30,P="...",R=150,j=16,Y=200,U=1,$=2,W="Expected a function",z="__lodash_placeholder__",q="[object Arguments]",G="[object Array]",H="[object Boolean]",V="[object Date]",Z="[object Error]",X="[object Function]",K="[object Map]",Q="[object Number]",J="[object Object]",tt="[object RegExp]",nt="[object Set]",et="[object String]",rt="[object WeakMap]",it="[object ArrayBuffer]",at="[object Float32Array]",ut="[object Float64Array]",ot="[object Int8Array]",st="[object Int16Array]",ct="[object Int32Array]",lt="[object Uint8Array]",ht="[object Uint8ClampedArray]",ft="[object Uint16Array]",dt="[object Uint32Array]",pt=/\b__p \+= '';/g,gt=/\b(__p \+=) '' \+/g,yt=/(__e\(.*?\)|\b__t\)) \+\n'';/g,mt=/&(?:amp|lt|gt|quot|#39|#96);/g,vt=/[&<>"'`]/g,_t=RegExp(mt.source),bt=RegExp(vt.source),xt=/<%-([\s\S]+?)%>/g,wt=/<%([\s\S]+?)%>/g,At=/<%=([\s\S]+?)%>/g,kt=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,Et=/^\w*$/,Mt=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,St=/^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g,Dt=RegExp(St.source),Ct=/[\u0300-\u036f\ufe20-\ufe23]/g,Tt=/\\(\\)?/g,Ft=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,Ot=/\w*$/,Lt=/^0[xX]/,It=/^\[object .+?Constructor\]$/,Bt=/^\d+$/,Nt=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,Pt=/($^)/,Rt=/['\n\r\u2028\u2029\\]/g,jt=function(){var t="[A-Z\\xc0-\\xd6\\xd8-\\xde]",n="[a-z\\xdf-\\xf6\\xf8-\\xff]+";return RegExp(t+"+(?="+t+n+")|"+t+"?"+n+"|"+t+"+|[0-9]+","g")}(),Yt=["Array","ArrayBuffer","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Math","Number","Object","RegExp","Set","String","_","clearTimeout","isFinite","parseFloat","parseInt","setTimeout","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap"],Ut=-1,$t={};$t[at]=$t[ut]=$t[ot]=$t[st]=$t[ct]=$t[lt]=$t[ht]=$t[ft]=$t[dt]=!0,$t[q]=$t[G]=$t[it]=$t[H]=$t[V]=$t[Z]=$t[X]=$t[K]=$t[Q]=$t[J]=$t[tt]=$t[nt]=$t[et]=$t[rt]=!1;var Wt={};Wt[q]=Wt[G]=Wt[it]=Wt[H]=Wt[V]=Wt[at]=Wt[ut]=Wt[ot]=Wt[st]=Wt[ct]=Wt[Q]=Wt[J]=Wt[tt]=Wt[et]=Wt[lt]=Wt[ht]=Wt[ft]=Wt[dt]=!0,Wt[Z]=Wt[X]=Wt[K]=Wt[nt]=Wt[rt]=!1;var zt={"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss"},qt={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},Gt={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},Ht={"function":!0,object:!0},Vt={0:"x30",1:"x31",2:"x32",3:"x33",4:"x34",5:"x35",6:"x36",7:"x37",8:"x38",9:"x39",A:"x41",B:"x42",C:"x43",D:"x44",E:"x45",F:"x46",a:"x61",b:"x62",c:"x63",d:"x64",e:"x65",f:"x66",n:"x6e",r:"x72",t:"x74",u:"x75",v:"x76",x:"x78"},Zt={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Xt=Ht[typeof e]&&e&&!e.nodeType&&e,Kt=Ht[typeof n]&&n&&!n.nodeType&&n,Qt=Xt&&Kt&&"object"==typeof t&&t&&t.Object&&t,Jt=Ht[typeof self]&&self&&self.Object&&self,tn=Ht[typeof window]&&window&&window.Object&&window,nn=Kt&&Kt.exports===Xt&&Xt,en=Qt||tn!==(this&&this.window)&&tn||Jt||this,rn=k();"function"==typeof define&&"object"==typeof define.amd&&define.amd?(en._=rn,define(function(){return rn})):Xt&&Kt?nn?(Kt.exports=rn)._=rn:Xt._=rn:en._=rn}).call(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],52:[function(t,n){n.exports={graphlib:t("./lib/graphlib"),layout:t("./lib/layout"),debug:t("./lib/debug"),util:{time:t("./lib/util").time,notime:t("./lib/util").notime},version:t("./lib/version")}},{"./lib/debug":57,"./lib/graphlib":58,"./lib/layout":60,"./lib/util":80,"./lib/version":81}],53:[function(t,n){"use strict";function e(t){function n(t){return function(n){return t.edge(n).weight}}var e="greedy"===t.graph().acyclicer?u(t,n(t)):r(t);a.each(e,function(n){var e=t.edge(n);t.removeEdge(n),e.forwardName=n.name,e.reversed=!0,t.setEdge(n.w,n.v,e,a.uniqueId("rev"))})}function r(t){function n(u){a.has(i,u)||(i[u]=!0,r[u]=!0,a.each(t.outEdges(u),function(t){a.has(r,t.w)?e.push(t):n(t.w)}),delete r[u])}var e=[],r={},i={};return a.each(t.nodes(),n),e}function i(t){a.each(t.edges(),function(n){var e=t.edge(n);if(e.reversed){t.removeEdge(n);var r=e.forwardName;delete e.reversed,delete e.forwardName,t.setEdge(n.w,n.v,e,r)}})}var a=t("./lodash"),u=t("./greedy-fas");n.exports={run:e,undo:i}},{"./greedy-fas":59,"./lodash":61}],54:[function(t,n){function e(t){function n(e){var a=t.children(e),u=t.node(e);if(a.length&&i.each(a,n),i.has(u,"minRank")){u.borderLeft=[],u.borderRight=[];for(var o=u.minRank,s=u.maxRank+1;s>o;++o)r(t,"borderLeft","_bl",e,u,o),r(t,"borderRight","_br",e,u,o)}}i.each(t.children(),n)}function r(t,n,e,r,i,u){var o={width:0,height:0,rank:u,borderType:n},s=i[n][u-1],c=a.addDummyNode(t,"border",o,e);i[n][u]=c,t.setParent(c,r),s&&t.setEdge(s,c,{weight:1})}var i=t("./lodash"),a=t("./util");n.exports=e},{"./lodash":61,"./util":80}],55:[function(t,n){"use strict";function e(t){var n=t.graph().rankdir.toLowerCase();("lr"===n||"rl"===n)&&i(t)}function r(t){var n=t.graph().rankdir.toLowerCase();("bt"===n||"rl"===n)&&u(t),("lr"===n||"rl"===n)&&(s(t),i(t))}function i(t){l.each(t.nodes(),function(n){a(t.node(n))}),l.each(t.edges(),function(n){a(t.edge(n))})}function a(t){var n=t.width;t.width=t.height,t.height=n}function u(t){l.each(t.nodes(),function(n){o(t.node(n))}),l.each(t.edges(),function(n){var e=t.edge(n);l.each(e.points,o),l.has(e,"y")&&o(e)})}function o(t){t.y=-t.y}function s(t){l.each(t.nodes(),function(n){c(t.node(n))}),l.each(t.edges(),function(n){var e=t.edge(n);l.each(e.points,c),l.has(e,"x")&&c(e)})}function c(t){var n=t.x;t.x=t.y,t.y=n}var l=t("./lodash");n.exports={adjust:e,undo:r}},{"./lodash":61}],56:[function(t,n){function e(){var t={};t._next=t._prev=t,this._sentinel=t}function r(t){t._prev._next=t._next,t._next._prev=t._prev,delete t._next,delete t._prev}function i(t,n){return"_next"!==t&&"_prev"!==t?n:void 0}n.exports=e,e.prototype.dequeue=function(){var t=this._sentinel,n=t._prev;return n!==t?(r(n),n):void 0},e.prototype.enqueue=function(t){var n=this._sentinel;t._prev&&t._next&&r(t),t._next=n._next,n._next._prev=t,n._next=t,t._prev=n},e.prototype.toString=function(){for(var t=[],n=this._sentinel,e=n._prev;e!==n;)t.push(JSON.stringify(e,i)),e=e._prev;return"["+t.join(", ")+"]"}},{}],57:[function(t,n){function e(t){var n=i.buildLayerMatrix(t),e=new a({compound:!0,multigraph:!0}).setGraph({});return r.each(t.nodes(),function(n){e.setNode(n,{label:n}),e.setParent(n,"layer"+t.node(n).rank)}),r.each(t.edges(),function(t){e.setEdge(t.v,t.w,{},t.name)}),r.each(n,function(t,n){var i="layer"+n;e.setNode(i,{rank:"same"}),r.reduce(t,function(t,n){return e.setEdge(t,n,{style:"invis"}),n})}),e}var r=t("./lodash"),i=t("./util"),a=t("./graphlib").Graph;n.exports={debugOrdering:e}},{"./graphlib":58,"./lodash":61,"./util":80}],58:[function(t,n){var e;if("function"==typeof t)try{e=t("graphlib")}catch(r){}e||(e=window.graphlib),n.exports=e},{graphlib:82}],59:[function(t,n){function e(t,n){if(t.nodeCount()<=1)return[];var e=a(t,n||l),i=r(e.graph,e.buckets,e.zeroIdx);return o.flatten(o.map(i,function(n){return t.outEdges(n.v,n.w)}),!0)}function r(t,n,e){for(var r,a=[],u=n[n.length-1],o=n[0];t.nodeCount();){for(;r=o.dequeue();)i(t,n,e,r);for(;r=u.dequeue();)i(t,n,e,r);if(t.nodeCount())for(var s=n.length-2;s>0;--s)if(r=n[s].dequeue()){a=a.concat(i(t,n,e,r,!0));break}}return a}function i(t,n,e,r,i){var a=i?[]:void 0;return o.each(t.inEdges(r.v),function(r){var o=t.edge(r),s=t.node(r.v);i&&a.push({v:r.v,w:r.w}),s.out-=o,u(n,e,s)}),o.each(t.outEdges(r.v),function(r){var i=t.edge(r),a=r.w,o=t.node(a);o["in"]-=i,u(n,e,o)}),t.removeNode(r.v),a}function a(t,n){var e=new s,r=0,i=0;o.each(t.nodes(),function(t){e.setNode(t,{v:t,"in":0,out:0})}),o.each(t.edges(),function(t){var a=e.edge(t.v,t.w)||0,u=n(t),o=a+u;e.setEdge(t.v,t.w,o),i=Math.max(i,e.node(t.v).out+=u),r=Math.max(r,e.node(t.w)["in"]+=u)});var a=o.range(i+r+3).map(function(){return new c}),l=r+1;return o.each(e.nodes(),function(t){u(a,l,e.node(t))}),{graph:e,buckets:a,zeroIdx:l}}function u(t,n,e){e.out?e["in"]?t[e.out-e["in"]+n].enqueue(e):t[t.length-1].enqueue(e):t[0].enqueue(e)}var o=t("./lodash"),s=t("./graphlib").Graph,c=t("./data/list");n.exports=e;var l=o.constant(1)},{"./data/list":56,"./graphlib":58,"./lodash":61}],60:[function(t,n){"use strict";function e(t,n){var e=n&&n.debugTiming?O.time:O.notime;e("layout",function(){var n=e(" buildLayoutGraph",function(){return a(t)});e(" runLayout",function(){r(n,e)}),e(" updateInputGraph",function(){i(t,n)})})}function r(t,n){n(" makeSpaceForEdgeLabels",function(){u(t)}),n(" removeSelfEdges",function(){g(t)}),n(" acyclic",function(){x.run(t)}),n(" nestingGraph.run",function(){S.run(t)}),n(" rank",function(){A(O.asNonCompoundGraph(t))}),n(" injectEdgeLabelProxies",function(){o(t)}),n(" removeEmptyRanks",function(){M(t)}),n(" nestingGraph.cleanup",function(){S.cleanup(t)}),n(" normalizeRanks",function(){k(t)}),n(" assignRankMinMax",function(){s(t)}),n(" removeEdgeLabelProxies",function(){c(t)}),n(" normalize.run",function(){w.run(t)}),n(" parentDummyChains",function(){E(t)}),n(" addBorderSegments",function(){D(t)}),n(" order",function(){T(t)}),n(" insertSelfEdges",function(){y(t)}),n(" adjustCoordinateSystem",function(){C.adjust(t)}),n(" position",function(){F(t)}),n(" positionSelfEdges",function(){m(t)}),n(" removeBorderNodes",function(){p(t)}),n(" normalize.undo",function(){w.undo(t)}),n(" fixupEdgeLabelCoords",function(){f(t)}),n(" undoCoordinateSystem",function(){C.undo(t)}),n(" translateGraph",function(){l(t)}),n(" assignNodeIntersects",function(){h(t)}),n(" reversePoints",function(){d(t)}),n(" acyclic.undo",function(){x.undo(t)})}function i(t,n){b.each(t.nodes(),function(e){var r=t.node(e),i=n.node(e);r&&(r.x=i.x,r.y=i.y,n.children(e).length&&(r.width=i.width,r.height=i.height))}),b.each(t.edges(),function(e){var r=t.edge(e),i=n.edge(e);r.points=i.points,b.has(i,"x")&&(r.x=i.x,r.y=i.y)}),t.graph().width=n.graph().width,t.graph().height=n.graph().height}function a(t){var n=new L({multigraph:!0,compound:!0}),e=_(t.graph());return n.setGraph(b.merge({},B,v(e,I),b.pick(e,N))),b.each(t.nodes(),function(e){var r=_(t.node(e));n.setNode(e,b.defaults(v(r,P),R)),n.setParent(e,t.parent(e))}),b.each(t.edges(),function(e){var r=_(t.edge(e));n.setEdge(e,b.merge({},Y,v(r,j),b.pick(r,U)))}),n}function u(t){var n=t.graph();n.ranksep/=2,b.each(t.edges(),function(e){var r=t.edge(e);r.minlen*=2,"c"!==r.labelpos.toLowerCase()&&("TB"===n.rankdir||"BT"===n.rankdir?r.width+=r.labeloffset:r.height+=r.labeloffset)})}function o(t){b.each(t.edges(),function(n){var e=t.edge(n);if(e.width&&e.height){var r=t.node(n.v),i=t.node(n.w),a={rank:(i.rank-r.rank)/2+r.rank,e:n};O.addDummyNode(t,"edge-proxy",a,"_ep")}})}function s(t){var n=0;b.each(t.nodes(),function(e){var r=t.node(e);r.borderTop&&(r.minRank=t.node(r.borderTop).rank,r.maxRank=t.node(r.borderBottom).rank,n=b.max(n,r.maxRank))}),t.graph().maxRank=n}function c(t){b.each(t.nodes(),function(n){var e=t.node(n);"edge-proxy"===e.dummy&&(t.edge(e.e).labelRank=e.rank,t.removeNode(n))})}function l(t){function n(t){var n=t.x,u=t.y,o=t.width,s=t.height;e=Math.min(e,n-o/2),r=Math.max(r,n+o/2),i=Math.min(i,u-s/2),a=Math.max(a,u+s/2)}var e=Number.POSITIVE_INFINITY,r=0,i=Number.POSITIVE_INFINITY,a=0,u=t.graph(),o=u.marginx||0,s=u.marginy||0;b.each(t.nodes(),function(e){n(t.node(e))}),b.each(t.edges(),function(e){var r=t.edge(e);b.has(r,"x")&&n(r)}),e-=o,i-=s,b.each(t.nodes(),function(n){var r=t.node(n);r.x-=e,r.y-=i}),b.each(t.edges(),function(n){var r=t.edge(n);b.each(r.points,function(t){t.x-=e,t.y-=i}),b.has(r,"x")&&(r.x-=e),b.has(r,"y")&&(r.y-=i)}),u.width=r-e+o,u.height=a-i+s}function h(t){b.each(t.edges(),function(n){var e,r,i=t.edge(n),a=t.node(n.v),u=t.node(n.w);i.points?(e=i.points[0],r=i.points[i.points.length-1]):(i.points=[],e=u,r=a),i.points.unshift(O.intersectRect(a,e)),i.points.push(O.intersectRect(u,r))})}function f(t){b.each(t.edges(),function(n){var e=t.edge(n);if(b.has(e,"x"))switch(("l"===e.labelpos||"r"===e.labelpos)&&(e.width-=e.labeloffset),e.labelpos){case"l":e.x-=e.width/2+e.labeloffset;break;case"r":e.x+=e.width/2+e.labeloffset}})}function d(t){b.each(t.edges(),function(n){var e=t.edge(n);e.reversed&&e.points.reverse()})}function p(t){b.each(t.nodes(),function(n){if(t.children(n).length){var e=t.node(n),r=t.node(e.borderTop),i=t.node(e.borderBottom),a=t.node(b.last(e.borderLeft)),u=t.node(b.last(e.borderRight));e.width=Math.abs(u.x-a.x),e.height=Math.abs(i.y-r.y),e.x=a.x+e.width/2,e.y=r.y+e.height/2}}),b.each(t.nodes(),function(n){"border"===t.node(n).dummy&&t.removeNode(n)})}function g(t){b.each(t.edges(),function(n){if(n.v===n.w){var e=t.node(n.v);e.selfEdges||(e.selfEdges=[]),e.selfEdges.push({e:n,label:t.edge(n)}),t.removeEdge(n)}})}function y(t){var n=O.buildLayerMatrix(t);b.each(n,function(n){var e=0;b.each(n,function(n,r){var i=t.node(n);i.order=r+e,b.each(i.selfEdges,function(n){O.addDummyNode(t,"selfedge",{width:n.label.width,height:n.label.height,rank:i.rank,order:r+ ++e,e:n.e,label:n.label},"_se")}),delete i.selfEdges})})}function m(t){b.each(t.nodes(),function(n){var e=t.node(n);if("selfedge"===e.dummy){var r=t.node(e.e.v),i=r.x+r.width/2,a=r.y,u=e.x-i,o=r.height/2;t.setEdge(e.e,e.label),t.removeNode(n),e.label.points=[{x:i+2*u/3,y:a-o},{x:i+5*u/6,y:a-o},{x:i+u,y:a},{x:i+5*u/6,y:a+o},{x:i+2*u/3,y:a+o}],e.label.x=e.x,e.label.y=e.y}})}function v(t,n){return b.mapValues(b.pick(t,n),Number)}function _(t){var n={};return b.each(t,function(t,e){n[e.toLowerCase()]=t}),n}var b=t("./lodash"),x=t("./acyclic"),w=t("./normalize"),A=t("./rank"),k=t("./util").normalizeRanks,E=t("./parent-dummy-chains"),M=t("./util").removeEmptyRanks,S=t("./nesting-graph"),D=t("./add-border-segments"),C=t("./coordinate-system"),T=t("./order"),F=t("./position"),O=t("./util"),L=t("./graphlib").Graph;n.exports=e;var I=["nodesep","edgesep","ranksep","marginx","marginy"],B={ranksep:50,edgesep:20,nodesep:50,rankdir:"tb"},N=["acyclicer","ranker","rankdir","align"],P=["width","height"],R={width:0,height:0},j=["minlen","weight","width","height","labeloffset"],Y={minlen:1,weight:1,width:0,height:0,labeloffset:10,labelpos:"r"},U=["labelpos"]},{"./acyclic":53,"./add-border-segments":54,"./coordinate-system":55,"./graphlib":58,"./lodash":61,"./nesting-graph":62,"./normalize":63,"./order":68,"./parent-dummy-chains":73,"./position":75,"./rank":77,"./util":80}],61:[function(t,n){n.exports=t(49)},{"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/lodash.js":49,lodash:102}],62:[function(t,n){function e(t){var n=s.addDummyNode(t,"root",{},"_root"),e=i(t),u=o.max(e)-1,c=2*u+1;t.graph().nestingRoot=n,o.each(t.edges(),function(n){t.edge(n).minlen*=c});var l=a(t)+1;o.each(t.children(),function(i){r(t,n,c,l,u,e,i)}),t.graph().nodeRankFactor=c}function r(t,n,e,i,a,u,c){var l=t.children(c);if(!l.length)return void(c!==n&&t.setEdge(n,c,{weight:0,minlen:e}));var h=s.addBorderNode(t,"_bt"),f=s.addBorderNode(t,"_bb"),d=t.node(c);t.setParent(h,c),d.borderTop=h,t.setParent(f,c),d.borderBottom=f,o.each(l,function(o){r(t,n,e,i,a,u,o);var s=t.node(o),l=s.borderTop?s.borderTop:o,d=s.borderBottom?s.borderBottom:o,p=s.borderTop?i:2*i,g=l!==d?1:a-u[c]+1;t.setEdge(h,l,{weight:p,minlen:g,nestingEdge:!0}),t.setEdge(d,f,{weight:p,minlen:g,nestingEdge:!0})}),t.parent(c)||t.setEdge(n,h,{weight:0,minlen:a+u[c]})}function i(t){function n(r,i){var a=t.children(r);a&&a.length&&o.each(a,function(t){n(t,i+1)}),e[r]=i}var e={};return o.each(t.children(),function(t){n(t,1)}),e}function a(t){return o.reduce(t.edges(),function(n,e){return n+t.edge(e).weight},0)}function u(t){var n=t.graph();t.removeNode(n.nestingRoot),delete n.nestingRoot,o.each(t.edges(),function(n){var e=t.edge(n);e.nestingEdge&&t.removeEdge(n)})}var o=t("./lodash"),s=t("./util");n.exports={run:e,cleanup:u}},{"./lodash":61,"./util":80}],63:[function(t,n){"use strict";function e(t){t.graph().dummyChains=[],a.each(t.edges(),function(n){r(t,n)})}function r(t,n){var e=n.v,r=t.node(e).rank,i=n.w,a=t.node(i).rank,o=n.name,s=t.edge(n),c=s.labelRank;if(a!==r+1){t.removeEdge(n);var l,h,f;for(f=0,++r;a>r;++f,++r)s.points=[],h={width:0,height:0,edgeLabel:s,edgeObj:n,rank:r},l=u.addDummyNode(t,"edge",h,"_d"),r===c&&(h.width=s.width,h.height=s.height,h.dummy="edge-label",h.labelpos=s.labelpos),t.setEdge(e,l,{weight:s.weight},o),0===f&&t.graph().dummyChains.push(l),e=l;t.setEdge(e,i,{weight:s.weight},o)}}function i(t){a.each(t.graph().dummyChains,function(n){var e,r=t.node(n),i=r.edgeLabel;for(t.setEdge(r.edgeObj,i);r.dummy;)e=t.successors(n)[0],t.removeNode(n),i.points.push({x:r.x,y:r.y}),"edge-label"===r.dummy&&(i.x=r.x,i.y=r.y,i.width=r.width,i.height=r.height),n=e,r=t.node(n)})}var a=t("./lodash"),u=t("./util");n.exports={run:e,undo:i}},{"./lodash":61,"./util":80}],64:[function(t,n){function e(t,n,e){var i,a={};r.each(e,function(e){for(var r,u,o=t.parent(e);o;){if(r=t.parent(o),r?(u=a[r],a[r]=o):(u=i,i=o),u&&u!==o)return void n.setEdge(u,o);o=r}})}var r=t("../lodash");n.exports=e},{"../lodash":61}],65:[function(t,n){function e(t,n){return r.map(n,function(n){var e=t.inEdges(n);if(e.length){var i=r.reduce(e,function(n,e){var r=t.edge(e),i=t.node(e.v);return{sum:n.sum+r.weight*i.order,weight:n.weight+r.weight}},{sum:0,weight:0});return{v:n,barycenter:i.sum/i.weight,weight:i.weight}}return{v:n}})}var r=t("../lodash");n.exports=e},{"../lodash":61}],66:[function(t,n){function e(t,n,e){var u=r(t),o=new a({compound:!0}).setGraph({root:u}).setDefaultNodeLabel(function(n){return t.node(n)});return i.each(t.nodes(),function(r){var a=t.node(r),s=t.parent(r);(a.rank===n||a.minRank<=n&&n<=a.maxRank)&&(o.setNode(r),o.setParent(r,s||u),i.each(t[e](r),function(n){var e=n.v===r?n.w:n.v,a=o.edge(e,r),u=i.isUndefined(a)?0:a.weight;o.setEdge(e,r,{weight:t.edge(n).weight+u})}),i.has(a,"minRank")&&o.setNode(r,{borderLeft:a.borderLeft[n],borderRight:a.borderRight[n]}))}),o}function r(t){for(var n;t.hasNode(n=i.uniqueId("_root")););return n}var i=t("../lodash"),a=t("../graphlib").Graph;n.exports=e},{"../graphlib":58,"../lodash":61}],67:[function(t,n){"use strict";function e(t,n){for(var e=0,i=1;i0;)n%2&&(e+=s[n+1]),n=n-1>>1,s[n]+=t.weight;c+=t.weight*e})),c}var i=t("../lodash");n.exports=e},{"../lodash":61}],68:[function(t,n){"use strict";function e(t){var n=d.maxRank(t),e=r(t,u.range(1,n+1),"inEdges"),c=r(t,u.range(n-1,-1,-1),"outEdges"),l=o(t);a(t,l);for(var h,f=Number.POSITIVE_INFINITY,p=0,g=0;4>g;++p,++g){i(p%2?e:c,p%4>=2),l=d.buildLayerMatrix(t);var y=s(t,l);f>y&&(g=0,h=u.cloneDeep(l),f=y)}a(t,h)}function r(t,n,e){return u.map(n,function(n){return l(t,n,e)})}function i(t,n){var e=new f;u.each(t,function(t){var r=t.graph().root,i=c(t,r,e,n);u.each(i.vs,function(n,e){t.node(n).order=e}),h(t,e,i.vs)})}function a(t,n){u.each(n,function(n){u.each(n,function(n,e){t.node(n).order=e})})}var u=t("../lodash"),o=t("./init-order"),s=t("./cross-count"),c=t("./sort-subgraph"),l=t("./build-layer-graph"),h=t("./add-subgraph-constraints"),f=t("../graphlib").Graph,d=t("../util");n.exports=e},{"../graphlib":58,"../lodash":61,"../util":80,"./add-subgraph-constraints":64,"./build-layer-graph":66,"./cross-count":67,"./init-order":69,"./sort-subgraph":71}],69:[function(t,n){"use strict";function e(t){function n(i){if(!r.has(e,i)){e[i]=!0;var a=t.node(i);u[a.rank].push(i),r.each(t.successors(i),n)}}var e={},i=r.filter(t.nodes(),function(n){return!t.children(n).length}),a=r.max(r.map(i,function(n){return t.node(n).rank})),u=r.map(r.range(a+1),function(){return[]}),o=r.sortBy(i,function(n){return t.node(n).rank});return r.each(o,n),u}var r=t("../lodash");n.exports=e},{"../lodash":61}],70:[function(t,n){"use strict";function e(t,n){var e={};a.each(t,function(t,n){var r=e[t.v]={indegree:0,"in":[],out:[],vs:[t.v],i:n};a.isUndefined(t.barycenter)||(r.barycenter=t.barycenter,r.weight=t.weight)}),a.each(n.edges(),function(t){var n=e[t.v],r=e[t.w];a.isUndefined(n)||a.isUndefined(r)||(r.indegree++,n.out.push(e[t.w]))});var i=a.filter(e,function(t){return!t.indegree});return r(i)}function r(t){function n(t){return function(n){n.merged||(a.isUndefined(n.barycenter)||a.isUndefined(t.barycenter)||n.barycenter>=t.barycenter)&&i(t,n)}}function e(n){return function(e){e["in"].push(n),0===--e.indegree&&t.push(e)}}for(var r=[];t.length;){var u=t.pop();r.push(u),a.each(u["in"].reverse(),n(u)),a.each(u.out,e(u))}return a.chain(r).filter(function(t){return!t.merged}).map(function(t){return a.pick(t,["vs","i","barycenter","weight"])}).value()}function i(t,n){var e=0,r=0;t.weight&&(e+=t.barycenter*t.weight,r+=t.weight),n.weight&&(e+=n.barycenter*n.weight,r+=n.weight),t.vs=n.vs.concat(t.vs),t.barycenter=e/r,t.weight=r,t.i=Math.min(n.i,t.i),n.merged=!0}var a=t("../lodash");n.exports=e},{"../lodash":61}],71:[function(t,n){function e(t,n,c,l){var h=t.children(n),f=t.node(n),d=f?f.borderLeft:void 0,p=f?f.borderRight:void 0,g={};d&&(h=a.filter(h,function(t){return t!==d&&t!==p}));var y=u(t,h);a.each(y,function(n){if(t.children(n.v).length){var r=e(t,n.v,c,l);g[n.v]=r,a.has(r,"barycenter")&&i(n,r)}});var m=o(y,c);r(m,g);var v=s(m,l);if(d&&(v.vs=a.flatten([d,v.vs,p],!0),t.predecessors(d).length)){var _=t.node(t.predecessors(d)[0]),b=t.node(t.predecessors(p)[0]);a.has(v,"barycenter")||(v.barycenter=0,v.weight=0),v.barycenter=(v.barycenter*v.weight+_.order+b.order)/(v.weight+2),v.weight+=2}return v}function r(t,n){a.each(t,function(t){t.vs=a.flatten(t.vs.map(function(t){return n[t]?n[t].vs:t}),!0)})}function i(t,n){a.isUndefined(t.barycenter)?(t.barycenter=n.barycenter,t.weight=n.weight):(t.barycenter=(t.barycenter*t.weight+n.barycenter*n.weight)/(t.weight+n.weight),t.weight+=n.weight)}var a=t("../lodash"),u=t("./barycenter"),o=t("./resolve-conflicts"),s=t("./sort");n.exports=e},{"../lodash":61,"./barycenter":65,"./resolve-conflicts":70,"./sort":72}],72:[function(t,n){function e(t,n){var e=u.partition(t,function(t){return a.has(t,"barycenter")}),o=e.lhs,s=a.sortBy(e.rhs,function(t){return-t.i}),c=[],l=0,h=0,f=0;o.sort(i(!!n)),f=r(c,s,f),a.each(o,function(t){f+=t.vs.length,c.push(t.vs),l+=t.barycenter*t.weight,h+=t.weight,f=r(c,s,f)});var d={vs:a.flatten(c,!0)};return h&&(d.barycenter=l/h,d.weight=h),d}function r(t,n,e){for(var r;n.length&&(r=a.last(n)).i<=e;)n.pop(),t.push(r.vs),e++;return e}function i(t){return function(n,e){return n.barycentere.barycenter?1:t?e.i-n.i:n.i-e.i}}var a=t("../lodash"),u=t("../util");n.exports=e},{"../lodash":61,"../util":80}],73:[function(t,n){function e(t){var n=i(t);a.each(t.graph().dummyChains,function(e){for(var i=t.node(e),a=i.edgeObj,u=r(t,n,a.v,a.w),o=u.path,s=u.lca,c=0,l=o[c],h=!0;e!==a.w;){if(i=t.node(e),h){for(;(l=o[c])!==s&&t.node(l).maxRanks||c>n[i].lim));for(a=i,i=r;(i=t.parent(i))!==a;)o.push(i);return{path:u.concat(o.reverse()),lca:a}}function i(t){function n(i){var u=r;a.each(t.children(i),n),e[i]={low:u,lim:r++}}var e={},r=0;return a.each(t.children(),n),e}var a=t("./lodash");n.exports=e},{"./lodash":61}],74:[function(t,n){"use strict";function e(t,n){function e(n,e){var u=0,o=0,s=n.length,c=y.last(e);return y.each(e,function(n,l){var h=i(t,n),f=h?t.node(h).order:s;(h||n===c)&&(y.each(e.slice(o,l+1),function(n){y.each(t.predecessors(n),function(e){var i=t.node(e),o=i.order;!(u>o||o>f)||i.dummy&&t.node(n).dummy||a(r,e,n)})}),o=l+1,u=f)}),e}var r={};return y.reduce(n,e),r}function r(t,n){function e(n,e,r,u,o){var s;y.each(y.range(e,r),function(e){s=n[e],t.node(s).dummy&&y.each(t.predecessors(s),function(n){var e=t.node(n);e.dummy&&(e.ordero)&&a(i,n,s)})})}function r(n,r){var i,a=-1,u=0;return y.each(r,function(o,s){if("border"===t.node(o).dummy){var c=t.predecessors(o);c.length&&(i=t.node(c[0]).order,e(r,u,s,a,i),u=s,a=i)}e(r,u,r.length,i,n.length)}),r}var i={};return y.reduce(n,r),i}function i(t,n){return t.node(n).dummy?y.find(t.predecessors(n),function(n){return t.node(n).dummy}):void 0}function a(t,n,e){if(n>e){var r=n;n=e,e=r}var i=t[n];i||(t[n]=i={}),i[e]=!0}function u(t,n,e){if(n>e){var r=n;n=e,e=r}return y.has(t[n],e)}function o(t,n,e,r){var i={},a={},o={};return y.each(n,function(t){y.each(t,function(t,n){i[t]=t,a[t]=t,o[t]=n})}),y.each(n,function(t){var n=-1;y.each(t,function(t){var s=r(t);if(s.length){s=y.sortBy(s,function(t){return o[t]});for(var c=(s.length-1)/2,l=Math.floor(c),h=Math.ceil(c);h>=l;++l){var f=s[l];a[t]===t&&nu.lim&&(o=u,s=!0);var c=p.filter(n.edges(),function(n){return s===d(t,t.node(n.v),o)&&s!==d(t,t.node(n.w),o)});return p.min(c,function(t){return y(n,t)})}function l(t,n,e,i){var a=e.v,o=e.w;t.removeEdge(a,o),t.setEdge(i.v,i.w,{}),u(t),r(t,n),h(t,n)}function h(t,n){var e=p.find(t.nodes(),function(t){return!n.node(t).parent}),r=v(t,e);r=r.slice(1),p.each(r,function(e){var r=t.node(e).parent,i=n.edge(e,r),a=!1;i||(i=n.edge(r,e),a=!0),n.node(e).rank=n.node(r).rank+(a?i.minlen:-i.minlen)})}function f(t,n,e){return t.hasEdge(n,e)}function d(t,n,e){return e.low<=n.lim&&n.lim<=e.lim}var p=t("../lodash"),g=t("./feasible-tree"),y=t("./util").slack,m=t("./util").longestPath,v=t("../graphlib").alg.preorder,_=t("../graphlib").alg.postorder,b=t("../util").simplify;n.exports=e,e.initLowLimValues=u,e.initCutValues=r,e.calcCutValue=a,e.leaveEdge=s,e.enterEdge=c,e.exchangeEdges=l},{"../graphlib":58,"../lodash":61,"../util":80,"./feasible-tree":76,"./util":79}],79:[function(t,n){"use strict";function e(t){function n(r){var a=t.node(r);if(i.has(e,r))return a.rank;e[r]=!0;var u=i.min(i.map(t.outEdges(r),function(e){return n(e.w)-t.edge(e).minlen}));return u===Number.POSITIVE_INFINITY&&(u=0),a.rank=u}var e={};i.each(t.sources(),n)}function r(t,n){return t.node(n.w).rank-t.node(n.v).rank-t.edge(n).minlen}var i=t("../lodash");n.exports={longestPath:e,slack:r}},{"../lodash":61}],80:[function(t,n){"use strict";function e(t,n,e,r){var i;do i=y.uniqueId(r);while(t.hasNode(i));return e.dummy=n,t.setNode(i,e),i}function r(t){var n=(new m).setGraph(t.graph());return y.each(t.nodes(),function(e){n.setNode(e,t.node(e))}),y.each(t.edges(),function(e){var r=n.edge(e.v,e.w)||{weight:0,minlen:1},i=t.edge(e);n.setEdge(e.v,e.w,{weight:r.weight+i.weight,minlen:Math.max(r.minlen,i.minlen)})}),n}function i(t){var n=new m({multigraph:t.isMultigraph()}).setGraph(t.graph());return y.each(t.nodes(),function(e){t.children(e).length||n.setNode(e,t.node(e))}),y.each(t.edges(),function(e){n.setEdge(e,t.edge(e))}),n}function a(t){var n=y.map(t.nodes(),function(n){var e={};return y.each(t.outEdges(n),function(n){e[n.w]=(e[n.w]||0)+t.edge(n).weight}),e});return y.zipObject(t.nodes(),n)}function u(t){var n=y.map(t.nodes(),function(n){var e={};return y.each(t.inEdges(n),function(n){e[n.v]=(e[n.v]||0)+t.edge(n).weight}),e});return y.zipObject(t.nodes(),n)}function o(t,n){var e=t.x,r=t.y,i=n.x-e,a=n.y-r,u=t.width/2,o=t.height/2;if(!i&&!a)throw new Error("Not possible to find intersection inside of the rectangle");var s,c;return Math.abs(a)*u>Math.abs(i)*o?(0>a&&(o=-o),s=o*i/a,c=o):(0>i&&(u=-u),s=u,c=u*a/i),{x:e+s,y:r+c}}function s(t){var n=y.map(y.range(f(t)+1),function(){return[]});return y.each(t.nodes(),function(e){var r=t.node(e),i=r.rank;y.isUndefined(i)||(n[i][r.order]=e)}),n}function c(t){var n=y.min(y.map(t.nodes(),function(n){return t.node(n).rank}));y.each(t.nodes(),function(e){var r=t.node(e);y.has(r,"rank")&&(r.rank-=n)})}function l(t){var n=y.min(y.map(t.nodes(),function(n){return t.node(n).rank})),e=[];y.each(t.nodes(),function(r){var i=t.node(r).rank-n;e[i]||(e[i]=[]),e[i].push(r)});var r=0,i=t.graph().nodeRankFactor;y.each(e,function(n,e){y.isUndefined(n)&&e%i!==0?--r:r&&y.each(n,function(n){t.node(n).rank+=r})})}function h(t,n,r,i){var a={width:0,height:0};return arguments.length>=4&&(a.rank=r,a.order=i),e(t,"border",a,n)}function f(t){return y.max(y.map(t.nodes(),function(n){var e=t.node(n).rank;return y.isUndefined(e)?void 0:e}))}function d(t,n){var e={lhs:[],rhs:[]};return y.each(t,function(t){n(t)?e.lhs.push(t):e.rhs.push(t)}),e}function p(t,n){var e=y.now();try{return n()}finally{console.log(t+" time: "+(y.now()-e)+"ms")}}function g(t,n){return n()}var y=t("./lodash"),m=t("./graphlib").Graph;n.exports={addDummyNode:e,simplify:r,asNonCompoundGraph:i,successorWeights:a,predecessorWeights:u,intersectRect:o,buildLayerMatrix:s,normalizeRanks:c,removeEmptyRanks:l,addBorderNode:h,maxRank:f,partition:d,time:p,notime:g}},{"./graphlib":58,"./lodash":61}],81:[function(t,n){n.exports="0.7.4"},{}],82:[function(t,n){n.exports=t(31)},{"./lib":98,"./lib/alg":89,"./lib/json":99,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/index.js":31}],83:[function(t,n){n.exports=t(32)},{"../lodash":100,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/alg/components.js":32}],84:[function(t,n){n.exports=t(33)},{"../lodash":100,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/alg/dfs.js":33}],85:[function(t,n){n.exports=t(34)},{"../lodash":100,"./dijkstra":86,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/alg/dijkstra-all.js":34}],86:[function(t,n){n.exports=t(35)},{"../data/priority-queue":96,"../lodash":100,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/alg/dijkstra.js":35}],87:[function(t,n){n.exports=t(36)},{"../lodash":100,"./tarjan":94,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/alg/find-cycles.js":36}],88:[function(t,n){n.exports=t(37)},{"../lodash":100,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/alg/floyd-warshall.js":37}],89:[function(t,n){n.exports=t(38)},{"./components":83,"./dijkstra":86,"./dijkstra-all":85,"./find-cycles":87,"./floyd-warshall":88,"./is-acyclic":90,"./postorder":91,"./preorder":92,"./prim":93,"./tarjan":94,"./topsort":95,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/alg/index.js":38}],90:[function(t,n){n.exports=t(39)},{"./topsort":95,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/alg/is-acyclic.js":39}],91:[function(t,n){n.exports=t(40)},{"./dfs":84,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/alg/postorder.js":40}],92:[function(t,n){n.exports=t(41)},{"./dfs":84,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/alg/preorder.js":41}],93:[function(t,n){n.exports=t(42)},{"../data/priority-queue":96,"../graph":97,"../lodash":100,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/alg/prim.js":42}],94:[function(t,n){n.exports=t(43)},{"../lodash":100,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/alg/tarjan.js":43}],95:[function(t,n){n.exports=t(44)},{"../lodash":100,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/alg/topsort.js":44}],96:[function(t,n){n.exports=t(45)},{"../lodash":100,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/data/priority-queue.js":45}],97:[function(t,n){n.exports=t(46)},{"./lodash":100,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/graph.js":46}],98:[function(t,n){n.exports=t(47)},{"./graph":97,"./version":101,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/index.js":47}],99:[function(t,n){n.exports=t(48)},{"./graph":97,"./lodash":100,"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/json.js":48}],100:[function(t,n){n.exports=t(49)},{"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/lodash.js":49,lodash:102}],101:[function(t,n){n.exports=t(50)},{"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/graphlib/lib/version.js":50}],102:[function(t,n){n.exports=t(51)},{"/Users/knut/source/mermaid/node_modules/dagre-d3/node_modules/lodash/index.js":51}],103:[function(t,n,e){(function(t){(function(){function r(t,n){return t.set(n[0],n[1]),t}function i(t,n){return t.add(n),t}function a(t,n,e){var r=e.length;switch(r){case 0:return t.call(n);case 1:return t.call(n,e[0]);case 2:return t.call(n,e[0],e[1]);case 3:return t.call(n,e[0],e[1],e[2])}return t.apply(n,e)}function u(t,n,e,r){for(var i=-1,a=t?t.length:0;++i-1}function f(t,n,e){for(var r=-1,i=t?t.length:0;++r-1;);return e}function O(t,n){for(var e=t.length;e--&&b(n,t[e],0)>-1;);return e}function L(t){return t&&t.Object===Object?t:null}function I(t,n){for(var e=t.length,r=0;e--;)t[e]===n&&r++;return r}function B(t){return Se[t]}function N(t){return De[t]}function P(t){return"\\"+Te[t]}function R(t,n){return null==t?X:t[n]}function j(t,n,e){for(var r=t.length,i=n+(e?1:-1);e?i--:++in,i=e?t.length:0,a=$i(0,i,this.__views__),u=a.start,o=a.end,s=o-u,c=r?o:u-1,l=this.__iteratees__,h=l.length,f=0,d=Jc(s,this.__takeCount__);if(!e||Q>i||i==s&&d==s)return Pr(t,this.__actions__);var p=[];t:for(;s--&&d>f;){c+=n;for(var g=-1,y=t[c];++ge)return!1;var r=n.length-1;return e==r?n.pop():zc.call(n,e,1),!0}function Hn(t){var n=this.__data__,e=pe(n,t);return 0>e?X:n[e][1]}function Vn(t){return pe(this.__data__,t)>-1}function Zn(t,n){var e=this.__data__,r=pe(e,t);return 0>r?e.push([t,n]):e[r][1]=n,this}function Xn(t){var n=-1,e=t?t.length:0;for(this.clear();++n=t?t:e),n!==X&&(t=t>=n?t:n)),t}function De(t,n,e,r,i,a,u){var s;if(r&&(s=a?r(t,i,a,u):r(t)),s!==X)return s;if(!mo(t))return t;var c=yh(t);if(c){if(s=zi(t),!n)return ei(t,s)}else{var l=Ui(t),h=l==Lt||l==It;if(mh(t))return zr(t,n);if(l==Pt||l==Dt||h&&!a){if(Y(t))return a?t:{};if(s=qi(h?{}:t),!n)return ii(t,ye(s,t))}else{if(!Me[l])return a?t:{};s=Gi(t,l,De,n)}}u||(u=new ae);var f=u.get(t);if(f)return f;if(u.set(t,s),!c)var d=e?Fi(t):rs(t);return o(d||t,function(i,a){d&&(a=i,i=t[a]),de(s,a,De(i,n,e,r,a,t,u))}),s}function Ce(t){var n=rs(t),e=n.length;return function(r){if(null==r)return!e;for(var i=e;i--;){var a=n[i],u=t[a],o=r[a];if(o===X&&!(a in Object(r))||!u(o))return!1}return!0}}function Te(t){return mo(t)?$c(t):{}}function Le(t,n,e){if("function"!=typeof t)throw new wc(J);return qc(function(){t.apply(X,e)},n)}function Ie(t,n,e,r){var i=-1,a=h,u=!0,o=t.length,s=[],c=n.length;if(!o)return s;e&&(n=d(n,D(e))),r?(a=f,u=!1):n.length>=Q&&(a=T,u=!1,n=new ee(n));t:for(;++ie&&(e=-e>i?0:i+e),r=r===X||r>i?i:jo(r),0>r&&(r+=i),r=e>r?0:Yo(r);r>e;)t[e++]=n;return t}function Ue(t,n){var e=[];return wl(t,function(t,r,i){n(t,r,i)&&e.push(t)}),e}function $e(t,n,e,r,i){var a=-1,u=t.length;for(e||(e=Vi),i||(i=[]);++a0&&e(o)?n>1?$e(o,n-1,e,r,i):p(i,o):r||(i[i.length]=o)}return i}function We(t,n){return t&&kl(t,n,rs)}function ze(t,n){return t&&El(t,n,rs)}function qe(t,n){return l(n,function(n){return po(t[n])})}function Ge(t,n){n=Qi(n,t)?[n]:$r(n);for(var e=0,r=n.length;null!=t&&r>e;)t=t[ca(n[e++])];return e&&e==r?t:X}function He(t,n,e){var r=n(t);return yh(t)?r:p(r,e(t))}function Ve(t,n){return t>n}function Ze(t,n){return null!=t&&(Cc.call(t,n)||"object"==typeof t&&n in t&&null===ji(t))}function Xe(t,n){return null!=t&&n in Object(t)}function Ke(t,n,e){return t>=Jc(n,e)&&t=120&&l.length>=120)?new ee(u&&l):X}l=t[0];var p=-1,g=o[0];t:for(;++pt}function cr(t,n){var e=-1,r=ro(t)?Array(t.length):[];return wl(t,function(t,i,a){r[++e]=n(t,i,a)}),r}function lr(t){var n=Pi(t);return 1==n.length&&n[0][2]?ia(n[0][0],n[0][1]):function(e){return e===t||rr(e,t,n)}}function hr(t,n){return Qi(t)&&ra(n)?ia(ca(t),n):function(e){var r=ts(e,t);return r===X&&r===n?es(e,t):nr(n,r,X,ft|dt)}}function fr(t,n,e,r,i){if(t!==n){if(!yh(n)&&!Lo(n))var a=is(n);o(a||n,function(u,o){if(a&&(o=u,u=n[o]),mo(u))i||(i=new ae),dr(t,n,o,e,fr,r,i);else{var s=r?r(t[o],u,o+"",t,n,i):X;s===X&&(s=u),fe(t,o,s)}})}}function dr(t,n,e,r,i,a,u){var o=t[e],s=n[e],c=u.get(s);if(c)return void fe(t,e,c);var l=a?a(o,s,e+"",t,n,u):X,h=l===X;h&&(l=s,yh(s)||Lo(s)?yh(o)?l=o:io(o)?l=ei(o):(h=!1,l=De(s,!0)):So(s)||no(s)?no(o)?l=$o(o):!mo(o)||r&&po(o)?(h=!1,l=De(s,!0)):l=o:h=!1),u.set(s,l),h&&i(l,s,r,a,u),u["delete"](s),fe(t,e,l)}function pr(t,n){var e=t.length;if(e)return n+=0>n?e:0,Xi(n,e)?t[n]:X}function gr(t,n,e){var r=-1;n=d(n.length?n:[Gs],D(Bi()));var i=cr(t,function(t){var e=d(n,function(n){return n(t)});return{criteria:e,index:++r,value:t}});return k(i,function(t,n){return Jr(t,n,e)})}function yr(t,n){return t=Object(t),g(n,function(n,e){return e in t&&(n[e]=t[e]),n},{})}function mr(t,n){for(var e=-1,r=Oi(t),i=r.length,a={};++e-1;)o!==t&&zc.call(o,s,1),zc.call(t,s,1);return t}function xr(t,n){for(var e=t?n.length:0,r=e-1;e--;){var i=n[e];if(e==r||i!==a){var a=i;if(Xi(i))zc.call(t,i,1);else if(Qi(i,t))delete t[ca(i)];else{var u=$r(i),o=oa(t,u);null!=o&&delete o[ca(Ta(u))]}}}return t}function wr(t,n){return t+Hc(nl()*(n-t+1))}function Ar(t,n,e,r){for(var i=-1,a=Qc(Gc((n-t)/(e||1)),0),u=Array(a);a--;)u[r?a:++i]=t,t+=e;return u}function kr(t,n){var e="";if(!t||1>n||n>wt)return e;do n%2&&(e+=t),n=Hc(n/2),n&&(t+=t);while(n);return e}function Er(t,n,e,r){n=Qi(n,t)?[n]:$r(n);for(var i=-1,a=n.length,u=a-1,o=t;null!=o&&++in&&(n=-n>i?0:i+n),e=e>i?i:e,0>e&&(e+=i),i=n>e?0:e-n>>>0,n>>>=0;for(var a=Array(i);++r=i){for(;i>r;){var a=r+i>>>1,u=t[a];null!==u&&!Oo(u)&&(e?n>=u:n>u)?r=a+1:i=a}return i}return Cr(t,n,Gs,e)}function Cr(t,n,e,r){n=e(n);for(var i=0,a=t?t.length:0,u=n!==n,o=null===n,s=Oo(n),c=n===X;a>i;){var l=Hc((i+a)/2),h=e(t[l]),f=h!==X,d=null===h,p=h===h,g=Oo(h);if(u)var y=r||p;else y=c?p&&(r||f):o?p&&f&&(r||!d):s?p&&f&&!d&&(r||!g):d||g?!1:r?n>=h:n>h;y?i=l+1:a=l}return Jc(a,Mt)}function Tr(t,n){for(var e=-1,r=t.length,i=0,a=[];++e=Q){var c=n?null:Sl(t);if(c)return z(c);u=!1,i=T,s=new ee}else s=n?[]:o;t:for(;++rr?n[r]:X;e(u,t[r],o)}return u}function Yr(t){return io(t)?t:[]}function Ur(t){return"function"==typeof t?t:Gs}function $r(t){return yh(t)?t:Ll(t)}function Wr(t,n,e){var r=t.length;return e=e===X?r:e,!n&&e>=r?t:Mr(t,n,e)}function zr(t,n){if(n)return t.slice();var e=new t.constructor(t.length);return t.copy(e),e}function qr(t){var n=new t.constructor(t.byteLength);return new Rc(n).set(new Rc(t)),n}function Gr(t,n){var e=n?qr(t.buffer):t.buffer;return new t.constructor(e,t.byteOffset,t.byteLength)}function Hr(t,n,e){var i=n?e($(t),!0):$(t);return g(i,r,new t.constructor)}function Vr(t){var n=new t.constructor(t.source,kn.exec(t));return n.lastIndex=t.lastIndex,n}function Zr(t,n,e){var r=n?e(z(t),!0):z(t);return g(r,i,new t.constructor)}function Xr(t){return bl?Object(bl.call(t)):{}}function Kr(t,n){var e=n?qr(t.buffer):t.buffer;return new t.constructor(e,t.byteOffset,t.length)}function Qr(t,n){if(t!==n){var e=t!==X,r=null===t,i=t===t,a=Oo(t),u=n!==X,o=null===n,s=n===n,c=Oo(n);if(!o&&!c&&!a&&t>n||a&&u&&s&&!o&&!c||r&&u&&s||!e&&s||!i)return 1;if(!r&&!a&&!c&&n>t||c&&e&&i&&!r&&!a||o&&e&&i||!u&&i||!s)return-1}return 0}function Jr(t,n,e){for(var r=-1,i=t.criteria,a=n.criteria,u=i.length,o=e.length;++r=o)return s;var c=e[r];return s*("desc"==c?-1:1)}}return t.index-n.index}function ti(t,n,e,r){for(var i=-1,a=t.length,u=e.length,o=-1,s=n.length,c=Qc(a-u,0),l=Array(s+c),h=!r;++oi)&&(l[e[i]]=t[i]);for(;c--;)l[o++]=t[i++];return l}function ni(t,n,e,r){for(var i=-1,a=t.length,u=-1,o=e.length,s=-1,c=n.length,l=Qc(a-o,0),h=Array(l+c),f=!r;++ii)&&(h[d+e[u]]=t[i++]);return h}function ei(t,n){var e=-1,r=t.length;for(n||(n=Array(r));++e1?e[i-1]:X,u=i>2?e[2]:X;for(a=t.length>3&&"function"==typeof a?(i--,a):X,u&&Ki(e[0],e[1],u)&&(a=3>i?X:a,i=1),n=Object(n);++ru&&o[0]!==c&&o[u-1]!==c?[]:W(o,c);if(u-=l.length,e>u)return ki(t,n,yi,r.placeholder,X,o,l,X,X,e-u);var h=this&&this!==je&&this instanceof r?i:t;return a(h,this,o)}var i=fi(t);return r}function pi(t){return function(n,e,r){var i=Object(n);if(e=Bi(e,3),!ro(n))var a=rs(n);var u=t(a||n,function(t,n){return a&&(n=t,t=i[n]),e(t,n,i)},r);return u>-1?n[a?a[u]:u]:X}}function gi(t){return zu(function(n){n=$e(n,1);var e=n.length,r=e,i=L.prototype.thru;for(t&&n.reverse();r--;){var a=n[r];if("function"!=typeof a)throw new wc(J);if(i&&!u&&"wrapper"==Li(a))var u=new L([],!0)}for(r=u?r:e;++r=Q)return u.plant(r).value();for(var i=0,a=e?n[i].apply(this,t):r;++im){var w=W(v,b);return ki(t,n,yi,l.placeholder,e,v,w,o,s,c-m)}var A=f?e:this,k=d?A[t]:t;return m=v.length,o?v=sa(v,o):g&&m>1&&v.reverse(),h&&m>s&&(v.length=s),this&&this!==je&&this instanceof l&&(k=y||fi(k)),k.apply(A,v)}var h=n&ct,f=n&et,d=n&rt,p=n&(at|ut),g=n&ht,y=d?X:fi(t);return l}function mi(t,n){return function(e,r){return Je(e,t,n(r),{})}}function vi(t){return function(n,e){var r;if(n===X&&e===X)return 0;if(n!==X&&(r=n),e!==X){if(r===X)return e;"string"==typeof n||"string"==typeof e?(n=Or(n),e=Or(e)):(n=Fr(n),e=Fr(e)),r=t(n,e)}return r}}function _i(t){return zu(function(n){return n=1==n.length&&yh(n[0])?d(n[0],D(Bi())):d($e(n,1,Zi),D(Bi())),zu(function(e){var r=this;return t(n,function(t){return a(t,r,e)})})})}function bi(t,n){n=n===X?" ":Or(n);var e=n.length;if(2>e)return e?kr(n,t):n;var r=kr(n,Gc(t/G(n)));return xe.test(n)?Wr(H(r),0,t).join(""):r.slice(0,t)}function xi(t,n,e,r){function i(){for(var n=-1,s=arguments.length,c=-1,l=r.length,h=Array(l+s),f=this&&this!==je&&this instanceof i?o:t;++cn?1:-1:Uo(r)||0,Ar(n,e,r,t)}}function Ai(t){return function(n,e){return("string"!=typeof n||"string"!=typeof e)&&(n=Uo(n),e=Uo(e)),t(n,e)}}function ki(t,n,e,r,i,a,u,o,s,c){var l=n&at,h=l?u:X,f=l?X:u,d=l?a:X,p=l?X:a;n|=l?ot:st,n&=~(l?st:ot),n&it||(n&=~(et|rt));var g=[t,n,i,d,h,p,f,o,s,c],y=e.apply(X,g);return ta(t)&&Ol(y,g),y.placeholder=r,y}function Ei(t){var n=bc[t];return function(t,e){if(t=Uo(t),e=Jc(jo(e),292)){var r=(zo(t)+"e").split("e"),i=n(r[0]+"e"+(+r[1]+e));return r=(zo(i)+"e").split("e"), -+(r[0]+"e"+(+r[1]-e))}return n(t)}}function Mi(t){return function(n){var e=Ui(n);return e==Bt?$(n):e==Yt?q(n):S(n,t(n))}}function Si(t,n,e,r,i,a,u,o){var s=n&rt;if(!s&&"function"!=typeof t)throw new wc(J);var c=r?r.length:0;if(c||(n&=~(ot|st),r=i=X),u=u===X?u:Qc(jo(u),0),o=o===X?o:jo(o),c-=i?i.length:0,n&st){var l=r,h=i;r=i=X}var f=s?X:Dl(t),d=[t,n,e,r,i,l,h,a,u,o];if(f&&aa(d,f),t=d[0],n=d[1],e=d[2],r=d[3],i=d[4],o=d[9]=null==d[9]?s?0:t.length:Qc(d[9]-c,0),!o&&n&(at|ut)&&(n&=~(at|ut)),n&&n!=et)p=n==at||n==ut?di(t,n,o):n!=ot&&n!=(et|ot)||i.length?yi.apply(X,d):xi(t,n,e,r);else var p=ci(t,n,e);var g=f?Ml:Ol;return g(p,d)}function Di(t,n,e,r,i,a){var u=i&dt,o=t.length,s=n.length;if(o!=s&&!(u&&s>o))return!1;var c=a.get(t);if(c)return c==n;var l=-1,h=!0,f=i&ft?new ee:X;for(a.set(t,n);++l-1&&t%1==0&&n>t}function Ki(t,n,e){if(!mo(e))return!1;var r=typeof n;return("number"==r?ro(e)&&Xi(n,e.length):"string"==r&&n in e)?to(e[n],t):!1}function Qi(t,n){if(yh(t))return!1;var e=typeof t;return"number"==e||"symbol"==e||"boolean"==e||null==t||Oo(t)?!0:pn.test(t)||!dn.test(t)||null!=n&&t in Object(n)}function Ji(t){var n=typeof t;return"string"==n||"number"==n||"symbol"==n||"boolean"==n?"__proto__"!==t:null===t}function ta(t){var e=Li(t),r=n[e];if("function"!=typeof r||!(e in In.prototype))return!1;if(t===r)return!0;var i=Dl(r);return!!i&&t===i[0]}function na(t){return!!Sc&&Sc in t}function ea(t){var n=t&&t.constructor,e="function"==typeof n&&n.prototype||kc;return t===e}function ra(t){return t===t&&!mo(t)}function ia(t,n){return function(e){return null==e?!1:e[t]===n&&(n!==X||t in Object(e))}}function aa(t,n){var e=t[1],r=n[1],i=e|r,a=(et|rt|ct)>i,u=r==ct&&e==at||r==ct&&e==lt&&t[7].length<=n[8]||r==(ct|lt)&&n[7].length<=n[8]&&e==at;if(!a&&!u)return t;r&et&&(t[2]=n[2],i|=e&et?0:it);var o=n[3];if(o){var s=t[3];t[3]=s?ti(s,o,n[4]):o,t[4]=s?W(t[3],nt):n[4]}return o=n[5],o&&(s=t[5],t[5]=s?ni(s,o,n[6]):o,t[6]=s?W(t[5],nt):n[6]),o=n[7],o&&(t[7]=o),r&ct&&(t[8]=null==t[8]?n[8]:Jc(t[8],n[8])),null==t[9]&&(t[9]=n[9]),t[0]=n[0],t[1]=i,t}function ua(t,n,e,r,i,a){return mo(t)&&mo(n)&&fr(t,n,X,ua,a.set(n,t)),t}function oa(t,n){return 1==n.length?t:Ge(t,Mr(n,0,-1))}function sa(t,n){for(var e=t.length,r=Jc(n.length,e),i=ei(t);r--;){var a=n[r];t[r]=Xi(a,e)?i[a]:X}return t}function ca(t){if("string"==typeof t||Oo(t))return t;var n=t+"";return"0"==n&&1/t==-xt?"-0":n}function la(t){if(null!=t){try{return Dc.call(t)}catch(n){}try{return t+""}catch(n){}}return""}function ha(t){if(t instanceof In)return t.clone();var n=new L(t.__wrapped__,t.__chain__);return n.__actions__=ei(t.__actions__),n.__index__=t.__index__,n.__values__=t.__values__,n}function fa(t,n,e){n=(e?Ki(t,n,e):n===X)?1:Qc(jo(n),0);var r=t?t.length:0;if(!r||1>n)return[];for(var i=0,a=0,u=Array(Gc(r/n));r>i;)u[a++]=Mr(t,i,i+=n);return u}function da(t){for(var n=-1,e=t?t.length:0,r=0,i=[];++nn?0:n,r)):[]}function ya(t,n,e){var r=t?t.length:0;return r?(n=e||n===X?1:jo(n),n=r-n,Mr(t,0,0>n?0:n)):[]}function ma(t,n){return t&&t.length?Nr(t,Bi(n,3),!0,!0):[]}function va(t,n){return t&&t.length?Nr(t,Bi(n,3),!0):[]}function _a(t,n,e,r){var i=t?t.length:0;return i?(e&&"number"!=typeof e&&Ki(t,n,e)&&(e=0,r=i),Re(t,n,e,r)):[]}function ba(t,n,e){var r=t?t.length:0;if(!r)return-1;var i=null==e?0:jo(e);return 0>i&&(i=Qc(r+i,0)),_(t,Bi(n,3),i)}function xa(t,n,e){var r=t?t.length:0;if(!r)return-1;var i=r-1;return e!==X&&(i=jo(e),i=0>e?Qc(r+i,0):Jc(i,r-1)),_(t,Bi(n,3),i,!0)}function wa(t){var n=t?t.length:0;return n?$e(t,1):[]}function Aa(t){var n=t?t.length:0;return n?$e(t,xt):[]}function ka(t,n){var e=t?t.length:0;return e?(n=n===X?1:jo(n),$e(t,n)):[]}function Ea(t){for(var n=-1,e=t?t.length:0,r={};++ni&&(i=Qc(r+i,0)),b(t,n,i)}function Da(t){return ya(t,1)}function Ca(t,n){return t?Xc.call(t,n):""}function Ta(t){var n=t?t.length:0;return n?t[n-1]:X}function Fa(t,n,e){var r=t?t.length:0;if(!r)return-1;var i=r;if(e!==X&&(i=jo(e),i=(0>i?Qc(r+i,0):Jc(i,r-1))+1),n!==n)return j(t,i-1,!0);for(;i--;)if(t[i]===n)return i;return-1}function Oa(t,n){return t&&t.length?pr(t,jo(n)):X}function La(t,n){return t&&t.length&&n&&n.length?br(t,n):t}function Ia(t,n,e){return t&&t.length&&n&&n.length?br(t,n,Bi(e)):t}function Ba(t,n,e){return t&&t.length&&n&&n.length?br(t,n,X,e):t}function Na(t,n){var e=[];if(!t||!t.length)return e;var r=-1,i=[],a=t.length;for(n=Bi(n,3);++rr&&to(t[r],n))return r}return-1}function $a(t,n){return Dr(t,n,!0)}function Wa(t,n,e){return Cr(t,n,Bi(e),!0)}function za(t,n){var e=t?t.length:0;if(e){var r=Dr(t,n,!0)-1;if(to(t[r],n))return r}return-1}function qa(t){return t&&t.length?Tr(t):[]}function Ga(t,n){return t&&t.length?Tr(t,Bi(n)):[]}function Ha(t){return ga(t,1)}function Va(t,n,e){return t&&t.length?(n=e||n===X?1:jo(n),Mr(t,0,0>n?0:n)):[]}function Za(t,n,e){var r=t?t.length:0;return r?(n=e||n===X?1:jo(n),n=r-n,Mr(t,0>n?0:n,r)):[]}function Xa(t,n){return t&&t.length?Nr(t,Bi(n,3),!1,!0):[]}function Ka(t,n){return t&&t.length?Nr(t,Bi(n,3)):[]}function Qa(t){return t&&t.length?Lr(t):[]}function Ja(t,n){return t&&t.length?Lr(t,Bi(n)):[]}function tu(t,n){return t&&t.length?Lr(t,X,n):[]}function nu(t){if(!t||!t.length)return[];var n=0;return t=l(t,function(t){return io(t)?(n=Qc(t.length,n),!0):void 0}),M(n,function(n){return d(t,vr(n))})}function eu(t,n){if(!t||!t.length)return[];var e=nu(t);return null==n?e:d(e,function(t){return a(n,X,t)})}function ru(t,n){return jr(t||[],n||[],de)}function iu(t,n){return jr(t||[],n||[],Er)}function au(t){var e=n(t);return e.__chain__=!0,e}function uu(t,n){return n(t),t}function ou(t,n){return n(t)}function su(){return au(this)}function cu(){return new L(this.value(),this.__chain__)}function lu(){this.__values__===X&&(this.__values__=Po(this.value()));var t=this.__index__>=this.__values__.length,n=t?X:this.__values__[this.__index__++];return{done:t,value:n}}function hu(){return this}function fu(t){for(var n,r=this;r instanceof e;){var i=ha(r);i.__index__=0,i.__values__=X,n?a.__wrapped__=i:n=i;var a=i;r=r.__wrapped__}return a.__wrapped__=t,n}function du(){var t=this.__wrapped__;if(t instanceof In){var n=t;return this.__actions__.length&&(n=new In(this)),n=n.reverse(),n.__actions__.push({func:ou,args:[Pa],thisArg:X}),new L(n,this.__chain__)}return this.thru(Pa)}function pu(){return Pr(this.__wrapped__,this.__actions__)}function gu(t,n,e){var r=yh(t)?c:Ne;return e&&Ki(t,n,e)&&(n=X),r(t,Bi(n,3))}function yu(t,n){var e=yh(t)?l:Ue;return e(t,Bi(n,3))}function mu(t,n){return $e(Au(t,n),1)}function vu(t,n){return $e(Au(t,n),xt)}function _u(t,n,e){return e=e===X?1:jo(e),$e(Au(t,n),e)}function bu(t,n){var e=yh(t)?o:wl;return e(t,Bi(n,3))}function xu(t,n){var e=yh(t)?s:Al;return e(t,Bi(n,3))}function wu(t,n,e,r){t=ro(t)?t:ys(t),e=e&&!r?jo(e):0;var i=t.length;return 0>e&&(e=Qc(i+e,0)),Fo(t)?i>=e&&t.indexOf(n,e)>-1:!!i&&b(t,n,e)>-1}function Au(t,n){var e=yh(t)?d:cr;return e(t,Bi(n,3))}function ku(t,n,e,r){return null==t?[]:(yh(n)||(n=null==n?[]:[n]),e=r?X:e,yh(e)||(e=null==e?[]:[e]),gr(t,n,e))}function Eu(t,n,e){var r=yh(t)?g:A,i=arguments.length<3;return r(t,Bi(n,4),e,i,wl)}function Mu(t,n,e){var r=yh(t)?y:A,i=arguments.length<3;return r(t,Bi(n,4),e,i,Al)}function Su(t,n){var e=yh(t)?l:Ue;return n=Bi(n,3),e(t,function(t,e,r){return!n(t,e,r)})}function Du(t){var n=ro(t)?t:ys(t),e=n.length;return e>0?n[wr(0,e-1)]:X}function Cu(t,n,e){var r=-1,i=Po(t),a=i.length,u=a-1;for(n=(e?Ki(t,n,e):n===X)?1:Se(jo(n),0,a);++r0&&(e=n.apply(this,arguments)),1>=t&&(n=X),e}}function Pu(t,n,e){n=e?X:n;var r=Si(t,at,X,X,X,X,X,n);return r.placeholder=Pu.placeholder,r}function Ru(t,n,e){n=e?X:n;var r=Si(t,ut,X,X,X,X,X,n);return r.placeholder=Ru.placeholder,r}function ju(t,n,e){function r(n){var e=f,r=d;return f=d=X,v=n,g=t.apply(r,e)}function i(t){return v=t,y=qc(o,n),_?r(t):g}function a(t){var e=t-m,r=t-v,i=n-e;return b?Jc(i,p-r):i}function u(t){var e=t-m,r=t-v;return m===X||e>=n||0>e||b&&r>=p}function o(){var t=Lu();return u(t)?s(t):void(y=qc(o,a(t)))}function s(t){return y=X,x&&f?r(t):(f=d=X,g)}function c(){v=0,f=m=d=y=X}function l(){return y===X?g:s(Lu())}function h(){var t=Lu(),e=u(t);if(f=arguments,d=this,m=t,e){if(y===X)return i(m);if(b)return y=qc(o,n),r(m)}return y===X&&(y=qc(o,n)),g}var f,d,p,g,y,m,v=0,_=!1,b=!1,x=!0;if("function"!=typeof t)throw new wc(J);return n=Uo(n)||0,mo(e)&&(_=!!e.leading,b="maxWait"in e,p=b?Qc(Uo(e.maxWait)||0,n):p,x="trailing"in e?!!e.trailing:x),h.cancel=c,h.flush=l,h}function Yu(t){return Si(t,ht)}function Uu(t,n){if("function"!=typeof t||n&&"function"!=typeof n)throw new wc(J);var e=function(){var r=arguments,i=n?n.apply(this,r):r[0],a=e.cache;if(a.has(i))return a.get(i);var u=t.apply(this,r);return e.cache=a.set(i,u),u};return e.cache=new(Uu.Cache||Xn),e}function $u(t){if("function"!=typeof t)throw new wc(J);return function(){return!t.apply(this,arguments)}}function Wu(t){return Nu(2,t)}function zu(t,n){if("function"!=typeof t)throw new wc(J);return n=Qc(n===X?t.length-1:jo(n),0),function(){for(var e=arguments,r=-1,i=Qc(e.length-n,0),u=Array(i);++r-1&&t%1==0&&wt>=t}function mo(t){var n=typeof t;return!!t&&("object"==n||"function"==n)}function vo(t){return!!t&&"object"==typeof t}function _o(t){return vo(t)&&Ui(t)==Bt}function bo(t,n){return t===n||rr(t,n,Pi(n))}function xo(t,n,e){return e="function"==typeof e?e:X,rr(t,n,Pi(n),e)}function wo(t){return Mo(t)&&t!=+t}function Ao(t){if(Fl(t))throw new _c("This method is not supported with `core-js`. Try https://github.com/es-shims.");return ir(t)}function ko(t){return null===t}function Eo(t){return null==t}function Mo(t){return"number"==typeof t||vo(t)&&Oc.call(t)==Nt}function So(t){if(!vo(t)||Oc.call(t)!=Pt||Y(t))return!1;var n=ji(t);if(null===n)return!0;var e=Cc.call(n,"constructor")&&n.constructor;return"function"==typeof e&&e instanceof e&&Dc.call(e)==Fc}function Do(t){return mo(t)&&Oc.call(t)==jt}function Co(t){return go(t)&&t>=-wt&&wt>=t}function To(t){return vo(t)&&Ui(t)==Yt}function Fo(t){return"string"==typeof t||!yh(t)&&vo(t)&&Oc.call(t)==Ut}function Oo(t){return"symbol"==typeof t||vo(t)&&Oc.call(t)==$t}function Lo(t){return vo(t)&&yo(t.length)&&!!Ee[Oc.call(t)]}function Io(t){return t===X}function Bo(t){return vo(t)&&Ui(t)==Wt}function No(t){return vo(t)&&Oc.call(t)==zt}function Po(t){if(!t)return[];if(ro(t))return Fo(t)?H(t):ei(t);if(Uc&&t[Uc])return U(t[Uc]());var n=Ui(t),e=n==Bt?$:n==Yt?z:ys;return e(t)}function Ro(t){if(!t)return 0===t?t:0;if(t=Uo(t),t===xt||t===-xt){var n=0>t?-1:1;return n*At}return t===t?t:0}function jo(t){var n=Ro(t),e=n%1;return n===n?e?n-e:n:0}function Yo(t){return t?Se(jo(t),0,Et):0}function Uo(t){if("number"==typeof t)return t;if(Oo(t))return kt;if(mo(t)){var n=po(t.valueOf)?t.valueOf():t;t=mo(n)?n+"":n}if("string"!=typeof t)return 0===t?t:+t;t=t.replace(vn,"");var e=Sn.test(t);return e||Cn.test(t)?Oe(t.slice(2),e?2:8):Mn.test(t)?kt:+t}function $o(t){return ri(t,is(t))}function Wo(t){return Se(jo(t),-wt,wt)}function zo(t){return null==t?"":Or(t)}function qo(t,n){var e=Te(t);return n?ye(e,n):e}function Go(t,n){return v(t,Bi(n,3),We)}function Ho(t,n){return v(t,Bi(n,3),ze)}function Vo(t,n){return null==t?t:kl(t,Bi(n,3),is)}function Zo(t,n){return null==t?t:El(t,Bi(n,3),is)}function Xo(t,n){return t&&We(t,Bi(n,3))}function Ko(t,n){return t&&ze(t,Bi(n,3))}function Qo(t){return null==t?[]:qe(t,rs(t))}function Jo(t){return null==t?[]:qe(t,is(t))}function ts(t,n,e){var r=null==t?X:Ge(t,n);return r===X?e:r}function ns(t,n){return null!=t&&Wi(t,n,Ze)}function es(t,n){return null!=t&&Wi(t,n,Xe)}function rs(t){var n=ea(t);if(!n&&!ro(t))return ur(t);var e=Hi(t),r=!!e,i=e||[],a=i.length;for(var u in t)!Ze(t,u)||r&&("length"==u||Xi(u,a))||n&&"constructor"==u||i.push(u);return i}function is(t){for(var n=-1,e=ea(t),r=or(t),i=r.length,a=Hi(t),u=!!a,o=a||[],s=o.length;++nn){var r=t;t=n,n=r}if(e||t%1||n%1){var i=nl();return Jc(t+i*(n-t+Fe("1e-"+((i+"").length-1))),n)}return wr(t,n)}function xs(t){return Wh(zo(t).toLowerCase())}function ws(t){return t=zo(t),t&&t.replace(Fn,B).replace(ve,"")}function As(t,n,e){t=zo(t),n=Or(n);var r=t.length;return e=e===X?r:Se(jo(e),0,r),e-=n.length,e>=0&&t.indexOf(n,e)==e}function ks(t){return t=zo(t),t&&cn.test(t)?t.replace(on,N):t}function Es(t){return t=zo(t),t&&mn.test(t)?t.replace(yn,"\\$&"):t}function Ms(t,n,e){t=zo(t),n=jo(n);var r=n?G(t):0;if(!n||r>=n)return t;var i=(n-r)/2;return bi(Hc(i),e)+t+bi(Gc(i),e)}function Ss(t,n,e){t=zo(t),n=jo(n);var r=n?G(t):0;return n&&n>r?t+bi(n-r,e):t}function Ds(t,n,e){t=zo(t),n=jo(n);var r=n?G(t):0;return n&&n>r?bi(n-r,e)+t:t}function Cs(t,n,e){return e||null==n?n=0:n&&(n=+n),t=zo(t).replace(vn,""),tl(t,n||(En.test(t)?16:10))}function Ts(t,n,e){return n=(e?Ki(t,n,e):n===X)?1:jo(n),kr(zo(t),n)}function Fs(){var t=arguments,n=zo(t[0]);return t.length<3?n:el.call(n,t[1],t[2])}function Os(t,n,e){return e&&"number"!=typeof e&&Ki(t,n,e)&&(n=e=X),(e=e===X?Et:e>>>0)?(t=zo(t),t&&("string"==typeof n||null!=n&&!Do(n))&&(n=Or(n),""==n&&xe.test(t))?Wr(H(t),0,e):il.call(t,n,e)):[]}function Ls(t,n,e){return t=zo(t),e=Se(jo(e),0,t.length),t.lastIndexOf(Or(n),e)==e}function Is(t,e,r){var i=n.templateSettings;r&&Ki(t,e,r)&&(e=X),t=zo(t),e=wh({},e,i,he);var a,u,o=wh({},e.imports,i.imports,he),s=rs(o),c=C(o,s),l=0,h=e.interpolate||On,f="__p += '",d=xc((e.escape||On).source+"|"+h.source+"|"+(h===fn?An:On).source+"|"+(e.evaluate||On).source+"|$","g"),p="//# sourceURL="+("sourceURL"in e?e.sourceURL:"lodash.templateSources["+ ++ke+"]")+"\n";t.replace(d,function(n,e,r,i,o,s){return r||(r=i),f+=t.slice(l,s).replace(Ln,P),e&&(a=!0,f+="' +\n__e("+e+") +\n'"),o&&(u=!0,f+="';\n"+o+";\n__p += '"),r&&(f+="' +\n((__t = ("+r+")) == null ? '' : __t) +\n'"),l=s+n.length,n}),f+="';\n";var g=e.variable;g||(f="with (obj) {\n"+f+"\n}\n"),f=(u?f.replace(en,""):f).replace(rn,"$1").replace(an,"$1;"),f="function("+(g||"obj")+") {\n"+(g?"":"obj || (obj = {});\n")+"var __t, __p = ''"+(a?", __e = _.escape":"")+(u?", __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\n":";\n")+f+"return __p\n}";var y=zh(function(){return Function(s,p+"return "+f).apply(X,c)});if(y.source=f,ho(y))throw y;return y}function Bs(t){return zo(t).toLowerCase()}function Ns(t){return zo(t).toUpperCase()}function Ps(t,n,e){if(t=zo(t),t&&(e||n===X))return t.replace(vn,"");if(!t||!(n=Or(n)))return t;var r=H(t),i=H(n),a=F(r,i),u=O(r,i)+1;return Wr(r,a,u).join("")}function Rs(t,n,e){if(t=zo(t),t&&(e||n===X))return t.replace(bn,"");if(!t||!(n=Or(n)))return t;var r=H(t),i=O(r,H(n))+1;return Wr(r,0,i).join("")}function js(t,n,e){if(t=zo(t),t&&(e||n===X))return t.replace(_n,"");if(!t||!(n=Or(n)))return t;var r=H(t),i=F(r,H(n));return Wr(r,i).join("")}function Ys(t,n){var e=pt,r=gt;if(mo(n)){var i="separator"in n?n.separator:i;e="length"in n?jo(n.length):e,r="omission"in n?Or(n.omission):r}t=zo(t);var a=t.length;if(xe.test(t)){var u=H(t);a=u.length}if(e>=a)return t;var o=e-G(r);if(1>o)return r;var s=u?Wr(u,0,o).join(""):t.slice(0,o);if(i===X)return s+r;if(u&&(o+=s.length-o),Do(i)){if(t.slice(o).search(i)){var c,l=s;for(i.global||(i=xc(i.source,zo(kn.exec(i))+"g")),i.lastIndex=0;c=i.exec(l);)var h=c.index;s=s.slice(0,h===X?o:h)}}else if(t.indexOf(Or(i),o)!=o){var f=s.lastIndexOf(i);f>-1&&(s=s.slice(0,f))}return s+r}function Us(t){return t=zo(t),t&&sn.test(t)?t.replace(un,V):t}function $s(t,n,e){return t=zo(t),n=e?X:n,n===X&&(n=we.test(t)?be:xn),t.match(n)||[]}function Ws(t){var n=t?t.length:0,e=Bi();return t=n?d(t,function(t){if("function"!=typeof t[1])throw new wc(J);return[e(t[0]),t[1]]}):[],zu(function(e){for(var r=-1;++rt||t>wt)return[];var e=Et,r=Jc(t,Et);n=Bi(n),t-=Et;for(var i=M(r,n);++e0){if(++t>=yt)return e}else t=0;return Ml(e,r)}}(),Ll=Uu(function(t){var n=[];return zo(t).replace(gn,function(t,e,r,i){n.push(r?i.replace(wn,"$1"):e||t)}),n}),Il=zu(function(t,n){return io(t)?Ie(t,$e(n,1,io,!0)):[]}),Bl=zu(function(t,n){var e=Ta(n);return io(e)&&(e=X),io(t)?Ie(t,$e(n,1,io,!0),Bi(e)):[]}),Nl=zu(function(t,n){var e=Ta(n);return io(e)&&(e=X),io(t)?Ie(t,$e(n,1,io,!0),X,e):[]}),Pl=zu(function(t){var n=d(t,Yr);return n.length&&n[0]===t[0]?Qe(n):[]}),Rl=zu(function(t){var n=Ta(t),e=d(t,Yr);return n===Ta(e)?n=X:e.pop(),e.length&&e[0]===t[0]?Qe(e,Bi(n)):[]}),jl=zu(function(t){var n=Ta(t),e=d(t,Yr);return n===Ta(e)?n=X:e.pop(),e.length&&e[0]===t[0]?Qe(e,X,n):[]}),Yl=zu(La),Ul=zu(function(t,n){n=$e(n,1);var e=t?t.length:0,r=_e(t,n);return xr(t,d(n,function(t){return Xi(t,e)?+t:t}).sort(Qr)),r}),$l=zu(function(t){return Lr($e(t,1,io,!0))}),Wl=zu(function(t){var n=Ta(t);return io(n)&&(n=X),Lr($e(t,1,io,!0),Bi(n))}),zl=zu(function(t){var n=Ta(t);return io(n)&&(n=X),Lr($e(t,1,io,!0),X,n)}),ql=zu(function(t,n){return io(t)?Ie(t,n):[]}),Gl=zu(function(t){return Rr(l(t,io))}),Hl=zu(function(t){var n=Ta(t);return io(n)&&(n=X),Rr(l(t,io),Bi(n))}),Vl=zu(function(t){var n=Ta(t);return io(n)&&(n=X),Rr(l(t,io),X,n)}),Zl=zu(nu),Xl=zu(function(t){var n=t.length,e=n>1?t[n-1]:X;return e="function"==typeof e?(t.pop(),e):X,eu(t,e)}),Kl=zu(function(t){t=$e(t,1);var n=t.length,e=n?t[0]:0,r=this.__wrapped__,i=function(n){return _e(n,t)};return!(n>1||this.__actions__.length)&&r instanceof In&&Xi(e)?(r=r.slice(e,+e+(n?1:0)),r.__actions__.push({func:ou,args:[i],thisArg:X}),new L(r,this.__chain__).thru(function(t){return n&&!t.length&&t.push(X),t})):this.thru(i)}),Ql=ai(function(t,n,e){Cc.call(t,e)?++t[e]:t[e]=1}),Jl=pi(ba),th=pi(xa),nh=ai(function(t,n,e){Cc.call(t,e)?t[e].push(n):t[e]=[n]}),eh=zu(function(t,n,e){var r=-1,i="function"==typeof n,u=Qi(n),o=ro(t)?Array(t.length):[];return wl(t,function(t){var s=i?n:u&&null!=t?t[n]:X;o[++r]=s?a(s,t,e):tr(t,n,e)}),o}),rh=ai(function(t,n,e){t[e]=n}),ih=ai(function(t,n,e){t[e?0:1].push(n)},function(){return[[],[]]}),ah=zu(function(t,n){if(null==t)return[];var e=n.length;return e>1&&Ki(t,n[0],n[1])?n=[]:e>2&&Ki(n[0],n[1],n[2])&&(n=[n[0]]),n=1==n.length&&yh(n[0])?n[0]:$e(n,1,Zi),gr(t,n,[])}),uh=zu(function(t,n,e){var r=et;if(e.length){var i=W(e,Ii(uh));r|=ot}return Si(t,r,n,e,i)}),oh=zu(function(t,n,e){var r=et|rt;if(e.length){var i=W(e,Ii(oh));r|=ot}return Si(n,r,t,e,i)}),sh=zu(function(t,n){return Le(t,1,n)}),ch=zu(function(t,n,e){return Le(t,Uo(n)||0,e)});Uu.Cache=Xn;var lh=zu(function(t,n){n=1==n.length&&yh(n[0])?d(n[0],D(Bi())):d($e(n,1,Zi),D(Bi()));var e=n.length;return zu(function(r){for(var i=-1,u=Jc(r.length,e);++i=n}),yh=Array.isArray,mh=Bc?function(t){return t instanceof Bc}:rc,vh=Ai(sr),_h=Ai(function(t,n){return n>=t}),bh=ui(function(t,n){if(fl||ea(n)||ro(n))return void ri(n,rs(n),t);for(var e in n)Cc.call(n,e)&&de(t,e,n[e])}),xh=ui(function(t,n){if(fl||ea(n)||ro(n))return void ri(n,is(n),t);for(var e in n)de(t,e,n[e])}),wh=ui(function(t,n,e,r){ri(n,is(n),t,r)}),Ah=ui(function(t,n,e,r){ri(n,rs(n),t,r)}),kh=zu(function(t,n){return _e(t,$e(n,1))}),Eh=zu(function(t){return t.push(X,he),a(wh,X,t)}),Mh=zu(function(t){return t.push(X,ua),a(Fh,X,t)}),Sh=mi(function(t,n,e){t[n]=e},qs(Gs)),Dh=mi(function(t,n,e){Cc.call(t,n)?t[n].push(e):t[n]=[e]},Bi),Ch=zu(tr),Th=ui(function(t,n,e){fr(t,n,e)}),Fh=ui(function(t,n,e,r){fr(t,n,e,r)}),Oh=zu(function(t,n){return null==t?{}:(n=d($e(n,1),ca),yr(t,Ie(Oi(t),n)))}),Lh=zu(function(t,n){return null==t?{}:yr(t,d($e(n,1),ca))}),Ih=Mi(rs),Bh=Mi(is),Nh=hi(function(t,n,e){return n=n.toLowerCase(),t+(e?xs(n):n)}),Ph=hi(function(t,n,e){return t+(e?"-":"")+n.toLowerCase()}),Rh=hi(function(t,n,e){ -return t+(e?" ":"")+n.toLowerCase()}),jh=li("toLowerCase"),Yh=hi(function(t,n,e){return t+(e?"_":"")+n.toLowerCase()}),Uh=hi(function(t,n,e){return t+(e?" ":"")+Wh(n)}),$h=hi(function(t,n,e){return t+(e?" ":"")+n.toUpperCase()}),Wh=li("toUpperCase"),zh=zu(function(t,n){try{return a(t,X,n)}catch(e){return ho(e)?e:new _c(e)}}),qh=zu(function(t,n){return o($e(n,1),function(n){n=ca(n),t[n]=uh(t[n],t)}),t}),Gh=gi(),Hh=gi(!0),Vh=zu(function(t,n){return function(e){return tr(e,t,n)}}),Zh=zu(function(t,n){return function(e){return tr(t,e,n)}}),Xh=_i(d),Kh=_i(c),Qh=_i(m),Jh=wi(),tf=wi(!0),nf=vi(function(t,n){return t+n}),ef=Ei("ceil"),rf=vi(function(t,n){return t/n}),af=Ei("floor"),uf=vi(function(t,n){return t*n}),of=Ei("round"),sf=vi(function(t,n){return t-n});return n.after=Iu,n.ary=Bu,n.assign=bh,n.assignIn=xh,n.assignInWith=wh,n.assignWith=Ah,n.at=kh,n.before=Nu,n.bind=uh,n.bindAll=qh,n.bindKey=oh,n.castArray=Zu,n.chain=au,n.chunk=fa,n.compact=da,n.concat=pa,n.cond=Ws,n.conforms=zs,n.constant=qs,n.countBy=Ql,n.create=qo,n.curry=Pu,n.curryRight=Ru,n.debounce=ju,n.defaults=Eh,n.defaultsDeep=Mh,n.defer=sh,n.delay=ch,n.difference=Il,n.differenceBy=Bl,n.differenceWith=Nl,n.drop=ga,n.dropRight=ya,n.dropRightWhile=ma,n.dropWhile=va,n.fill=_a,n.filter=yu,n.flatMap=mu,n.flatMapDeep=vu,n.flatMapDepth=_u,n.flatten=wa,n.flattenDeep=Aa,n.flattenDepth=ka,n.flip=Yu,n.flow=Gh,n.flowRight=Hh,n.fromPairs=Ea,n.functions=Qo,n.functionsIn=Jo,n.groupBy=nh,n.initial=Da,n.intersection=Pl,n.intersectionBy=Rl,n.intersectionWith=jl,n.invert=Sh,n.invertBy=Dh,n.invokeMap=eh,n.iteratee=Hs,n.keyBy=rh,n.keys=rs,n.keysIn=is,n.map=Au,n.mapKeys=as,n.mapValues=us,n.matches=Vs,n.matchesProperty=Zs,n.memoize=Uu,n.merge=Th,n.mergeWith=Fh,n.method=Vh,n.methodOf=Zh,n.mixin=Xs,n.negate=$u,n.nthArg=Js,n.omit=Oh,n.omitBy=os,n.once=Wu,n.orderBy=ku,n.over=Xh,n.overArgs=lh,n.overEvery=Kh,n.overSome=Qh,n.partial=hh,n.partialRight=fh,n.partition=ih,n.pick=Lh,n.pickBy=ss,n.property=tc,n.propertyOf=nc,n.pull=Yl,n.pullAll=La,n.pullAllBy=Ia,n.pullAllWith=Ba,n.pullAt=Ul,n.range=Jh,n.rangeRight=tf,n.rearg=dh,n.reject=Su,n.remove=Na,n.rest=zu,n.reverse=Pa,n.sampleSize=Cu,n.set=ls,n.setWith=hs,n.shuffle=Tu,n.slice=Ra,n.sortBy=ah,n.sortedUniq=qa,n.sortedUniqBy=Ga,n.split=Os,n.spread=qu,n.tail=Ha,n.take=Va,n.takeRight=Za,n.takeRightWhile=Xa,n.takeWhile=Ka,n.tap=uu,n.throttle=Gu,n.thru=ou,n.toArray=Po,n.toPairs=Ih,n.toPairsIn=Bh,n.toPath=sc,n.toPlainObject=$o,n.transform=fs,n.unary=Hu,n.union=$l,n.unionBy=Wl,n.unionWith=zl,n.uniq=Qa,n.uniqBy=Ja,n.uniqWith=tu,n.unset=ds,n.unzip=nu,n.unzipWith=eu,n.update=ps,n.updateWith=gs,n.values=ys,n.valuesIn=ms,n.without=ql,n.words=$s,n.wrap=Vu,n.xor=Gl,n.xorBy=Hl,n.xorWith=Vl,n.zip=Zl,n.zipObject=ru,n.zipObjectDeep=iu,n.zipWith=Xl,n.entries=Ih,n.entriesIn=Bh,n.extend=xh,n.extendWith=wh,Xs(n,n),n.add=nf,n.attempt=zh,n.camelCase=Nh,n.capitalize=xs,n.ceil=ef,n.clamp=vs,n.clone=Xu,n.cloneDeep=Qu,n.cloneDeepWith=Ju,n.cloneWith=Ku,n.deburr=ws,n.divide=rf,n.endsWith=As,n.eq=to,n.escape=ks,n.escapeRegExp=Es,n.every=gu,n.find=Jl,n.findIndex=ba,n.findKey=Go,n.findLast=th,n.findLastIndex=xa,n.findLastKey=Ho,n.floor=af,n.forEach=bu,n.forEachRight=xu,n.forIn=Vo,n.forInRight=Zo,n.forOwn=Xo,n.forOwnRight=Ko,n.get=ts,n.gt=ph,n.gte=gh,n.has=ns,n.hasIn=es,n.head=Ma,n.identity=Gs,n.includes=wu,n.indexOf=Sa,n.inRange=_s,n.invoke=Ch,n.isArguments=no,n.isArray=yh,n.isArrayBuffer=eo,n.isArrayLike=ro,n.isArrayLikeObject=io,n.isBoolean=ao,n.isBuffer=mh,n.isDate=uo,n.isElement=oo,n.isEmpty=so,n.isEqual=co,n.isEqualWith=lo,n.isError=ho,n.isFinite=fo,n.isFunction=po,n.isInteger=go,n.isLength=yo,n.isMap=_o,n.isMatch=bo,n.isMatchWith=xo,n.isNaN=wo,n.isNative=Ao,n.isNil=Eo,n.isNull=ko,n.isNumber=Mo,n.isObject=mo,n.isObjectLike=vo,n.isPlainObject=So,n.isRegExp=Do,n.isSafeInteger=Co,n.isSet=To,n.isString=Fo,n.isSymbol=Oo,n.isTypedArray=Lo,n.isUndefined=Io,n.isWeakMap=Bo,n.isWeakSet=No,n.join=Ca,n.kebabCase=Ph,n.last=Ta,n.lastIndexOf=Fa,n.lowerCase=Rh,n.lowerFirst=jh,n.lt=vh,n.lte=_h,n.max=lc,n.maxBy=hc,n.mean=fc,n.meanBy=dc,n.min=pc,n.minBy=gc,n.stubArray=ec,n.stubFalse=rc,n.stubObject=ic,n.stubString=ac,n.stubTrue=uc,n.multiply=uf,n.nth=Oa,n.noConflict=Ks,n.noop=Qs,n.now=Lu,n.pad=Ms,n.padEnd=Ss,n.padStart=Ds,n.parseInt=Cs,n.random=bs,n.reduce=Eu,n.reduceRight=Mu,n.repeat=Ts,n.replace=Fs,n.result=cs,n.round=of,n.runInContext=Z,n.sample=Du,n.size=Fu,n.snakeCase=Yh,n.some=Ou,n.sortedIndex=ja,n.sortedIndexBy=Ya,n.sortedIndexOf=Ua,n.sortedLastIndex=$a,n.sortedLastIndexBy=Wa,n.sortedLastIndexOf=za,n.startCase=Uh,n.startsWith=Ls,n.subtract=sf,n.sum=yc,n.sumBy=mc,n.template=Is,n.times=oc,n.toFinite=Ro,n.toInteger=jo,n.toLength=Yo,n.toLower=Bs,n.toNumber=Uo,n.toSafeInteger=Wo,n.toString=zo,n.toUpper=Ns,n.trim=Ps,n.trimEnd=Rs,n.trimStart=js,n.truncate=Ys,n.unescape=Us,n.uniqueId=cc,n.upperCase=$h,n.upperFirst=Wh,n.each=bu,n.eachRight=xu,n.first=Ma,Xs(n,function(){var t={};return We(n,function(e,r){Cc.call(n.prototype,r)||(t[r]=e)}),t}(),{chain:!1}),n.VERSION=K,o(["bind","bindKey","curry","curryRight","partial","partialRight"],function(t){n[t].placeholder=n}),o(["drop","take"],function(t,n){In.prototype[t]=function(e){var r=this.__filtered__;if(r&&!n)return new In(this);e=e===X?1:Qc(jo(e),0);var i=this.clone();return r?i.__takeCount__=Jc(e,i.__takeCount__):i.__views__.push({size:Jc(e,Et),type:t+(i.__dir__<0?"Right":"")}),i},In.prototype[t+"Right"]=function(n){return this.reverse()[t](n).reverse()}}),o(["filter","map","takeWhile"],function(t,n){var e=n+1,r=e==vt||e==bt;In.prototype[t]=function(t){var n=this.clone();return n.__iteratees__.push({iteratee:Bi(t,3),type:e}),n.__filtered__=n.__filtered__||r,n}}),o(["head","last"],function(t,n){var e="take"+(n?"Right":"");In.prototype[t]=function(){return this[e](1).value()[0]}}),o(["initial","tail"],function(t,n){var e="drop"+(n?"":"Right");In.prototype[t]=function(){return this.__filtered__?new In(this):this[e](1)}}),In.prototype.compact=function(){return this.filter(Gs)},In.prototype.find=function(t){return this.filter(t).head()},In.prototype.findLast=function(t){return this.reverse().find(t)},In.prototype.invokeMap=zu(function(t,n){return"function"==typeof t?new In(this):this.map(function(e){return tr(e,t,n)})}),In.prototype.reject=function(t){return t=Bi(t,3),this.filter(function(n){return!t(n)})},In.prototype.slice=function(t,n){t=jo(t);var e=this;return e.__filtered__&&(t>0||0>n)?new In(e):(0>t?e=e.takeRight(-t):t&&(e=e.drop(t)),n!==X&&(n=jo(n),e=0>n?e.dropRight(-n):e.take(n-t)),e)},In.prototype.takeRightWhile=function(t){return this.reverse().takeWhile(t).reverse()},In.prototype.toArray=function(){return this.take(Et)},We(In.prototype,function(t,e){var r=/^(?:filter|find|map|reject)|While$/.test(e),i=/^(?:head|last)$/.test(e),a=n[i?"take"+("last"==e?"Right":""):e],u=i||/^find/.test(e);a&&(n.prototype[e]=function(){var e=this.__wrapped__,o=i?[1]:arguments,s=e instanceof In,c=o[0],l=s||yh(e),h=function(t){var e=a.apply(n,p([t],o));return i&&f?e[0]:e};l&&r&&"function"==typeof c&&1!=c.length&&(s=l=!1);var f=this.__chain__,d=!!this.__actions__.length,g=u&&!f,y=s&&!d;if(!u&&l){e=y?e:new In(this);var m=t.apply(e,o);return m.__actions__.push({func:ou,args:[h],thisArg:X}),new L(m,f)}return g&&y?t.apply(this,o):(m=this.thru(h),g?i?m.value()[0]:m.value():m)})}),o(["pop","push","shift","sort","splice","unshift"],function(t){var e=Ac[t],r=/^(?:push|sort|unshift)$/.test(t)?"tap":"thru",i=/^(?:pop|shift)$/.test(t);n.prototype[t]=function(){var t=arguments;if(i&&!this.__chain__){var n=this.value();return e.apply(yh(n)?n:[],t)}return this[r](function(n){return e.apply(yh(n)?n:[],t)})}}),We(In.prototype,function(t,e){var r=n[e];if(r){var i=r.name+"",a=dl[i]||(dl[i]=[]);a.push({name:e,func:r})}}),dl[yi(X,rt).name]=[{name:"wrapper",func:X}],In.prototype.clone=Bn,In.prototype.reverse=Nn,In.prototype.value=Pn,n.prototype.at=Kl,n.prototype.chain=su,n.prototype.commit=cu,n.prototype.next=lu,n.prototype.plant=fu,n.prototype.reverse=du,n.prototype.toJSON=n.prototype.valueOf=n.prototype.value=pu,Uc&&(n.prototype[Uc]=hu),n}var X,K="4.13.1",Q=200,J="Expected a function",tt="__lodash_hash_undefined__",nt="__lodash_placeholder__",et=1,rt=2,it=4,at=8,ut=16,ot=32,st=64,ct=128,lt=256,ht=512,ft=1,dt=2,pt=30,gt="...",yt=150,mt=16,vt=1,_t=2,bt=3,xt=1/0,wt=9007199254740991,At=1.7976931348623157e308,kt=0/0,Et=4294967295,Mt=Et-1,St=Et>>>1,Dt="[object Arguments]",Ct="[object Array]",Tt="[object Boolean]",Ft="[object Date]",Ot="[object Error]",Lt="[object Function]",It="[object GeneratorFunction]",Bt="[object Map]",Nt="[object Number]",Pt="[object Object]",Rt="[object Promise]",jt="[object RegExp]",Yt="[object Set]",Ut="[object String]",$t="[object Symbol]",Wt="[object WeakMap]",zt="[object WeakSet]",qt="[object ArrayBuffer]",Gt="[object DataView]",Ht="[object Float32Array]",Vt="[object Float64Array]",Zt="[object Int8Array]",Xt="[object Int16Array]",Kt="[object Int32Array]",Qt="[object Uint8Array]",Jt="[object Uint8ClampedArray]",tn="[object Uint16Array]",nn="[object Uint32Array]",en=/\b__p \+= '';/g,rn=/\b(__p \+=) '' \+/g,an=/(__e\(.*?\)|\b__t\)) \+\n'';/g,un=/&(?:amp|lt|gt|quot|#39|#96);/g,on=/[&<>"'`]/g,sn=RegExp(un.source),cn=RegExp(on.source),ln=/<%-([\s\S]+?)%>/g,hn=/<%([\s\S]+?)%>/g,fn=/<%=([\s\S]+?)%>/g,dn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,pn=/^\w*$/,gn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(\.|\[\])(?:\4|$))/g,yn=/[\\^$.*+?()[\]{}|]/g,mn=RegExp(yn.source),vn=/^\s+|\s+$/g,_n=/^\s+/,bn=/\s+$/,xn=/[a-zA-Z0-9]+/g,wn=/\\(\\)?/g,An=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,kn=/\w*$/,En=/^0x/i,Mn=/^[-+]0x[0-9a-f]+$/i,Sn=/^0b[01]+$/i,Dn=/^\[object .+?Constructor\]$/,Cn=/^0o[0-7]+$/i,Tn=/^(?:0|[1-9]\d*)$/,Fn=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,On=/($^)/,Ln=/['\n\r\u2028\u2029\\]/g,In="\\ud800-\\udfff",Bn="\\u0300-\\u036f\\ufe20-\\ufe23",Nn="\\u20d0-\\u20f0",Pn="\\u2700-\\u27bf",Rn="a-z\\xdf-\\xf6\\xf8-\\xff",jn="\\xac\\xb1\\xd7\\xf7",Yn="\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf",Un="\\u2000-\\u206f",$n=" \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",Wn="A-Z\\xc0-\\xd6\\xd8-\\xde",zn="\\ufe0e\\ufe0f",qn=jn+Yn+Un+$n,Gn="['’]",Hn="["+In+"]",Vn="["+qn+"]",Zn="["+Bn+Nn+"]",Xn="\\d+",Kn="["+Pn+"]",Qn="["+Rn+"]",Jn="[^"+In+qn+Xn+Pn+Rn+Wn+"]",te="\\ud83c[\\udffb-\\udfff]",ne="(?:"+Zn+"|"+te+")",ee="[^"+In+"]",re="(?:\\ud83c[\\udde6-\\uddff]){2}",ie="[\\ud800-\\udbff][\\udc00-\\udfff]",ae="["+Wn+"]",ue="\\u200d",oe="(?:"+Qn+"|"+Jn+")",se="(?:"+ae+"|"+Jn+")",ce="(?:"+Gn+"(?:d|ll|m|re|s|t|ve))?",le="(?:"+Gn+"(?:D|LL|M|RE|S|T|VE))?",he=ne+"?",fe="["+zn+"]?",de="(?:"+ue+"(?:"+[ee,re,ie].join("|")+")"+fe+he+")*",pe=fe+he+de,ge="(?:"+[Kn,re,ie].join("|")+")"+pe,ye="(?:"+[ee+Zn+"?",Zn,re,ie,Hn].join("|")+")",me=RegExp(Gn,"g"),ve=RegExp(Zn,"g"),_e=RegExp(te+"(?="+te+")|"+ye+pe,"g"),be=RegExp([ae+"?"+Qn+"+"+ce+"(?="+[Vn,ae,"$"].join("|")+")",se+"+"+le+"(?="+[Vn,ae+oe,"$"].join("|")+")",ae+"?"+oe+"+"+ce,ae+"+"+le,Xn,ge].join("|"),"g"),xe=RegExp("["+ue+In+Bn+Nn+zn+"]"),we=/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Ae=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","Reflect","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","isFinite","parseInt","setTimeout"],ke=-1,Ee={};Ee[Ht]=Ee[Vt]=Ee[Zt]=Ee[Xt]=Ee[Kt]=Ee[Qt]=Ee[Jt]=Ee[tn]=Ee[nn]=!0,Ee[Dt]=Ee[Ct]=Ee[qt]=Ee[Tt]=Ee[Gt]=Ee[Ft]=Ee[Ot]=Ee[Lt]=Ee[Bt]=Ee[Nt]=Ee[Pt]=Ee[jt]=Ee[Yt]=Ee[Ut]=Ee[Wt]=!1;var Me={};Me[Dt]=Me[Ct]=Me[qt]=Me[Gt]=Me[Tt]=Me[Ft]=Me[Ht]=Me[Vt]=Me[Zt]=Me[Xt]=Me[Kt]=Me[Bt]=Me[Nt]=Me[Pt]=Me[jt]=Me[Yt]=Me[Ut]=Me[$t]=Me[Qt]=Me[Jt]=Me[tn]=Me[nn]=!0,Me[Ot]=Me[Lt]=Me[Wt]=!1;var Se={"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss"},De={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},Ce={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},Te={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Fe=parseFloat,Oe=parseInt,Le="object"==typeof e&&e,Ie=Le&&"object"==typeof n&&n,Be=Ie&&Ie.exports===Le,Ne=L("object"==typeof t&&t),Pe=L("object"==typeof self&&self),Re=L("object"==typeof this&&this),je=Ne||Pe||Re||Function("return this")(),Ye=Z();(Pe||{})._=Ye,"function"==typeof define&&"object"==typeof define.amd&&define.amd?define(function(){return Ye}):Ie?((Ie.exports=Ye)._=Ye,Le._=Ye):je._=Ye}).call(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],104:[function(t,n,e){!function(t,r){"object"==typeof e&&"undefined"!=typeof n?n.exports=r():"function"==typeof define&&define.amd?define(r):t.moment=r()}(this,function(){"use strict";function e(){return sr.apply(null,arguments)}function r(t){sr=t}function i(t){return t instanceof Array||"[object Array]"===Object.prototype.toString.call(t)}function a(t){return t instanceof Date||"[object Date]"===Object.prototype.toString.call(t)}function u(t,n){var e,r=[];for(e=0;e0)for(e in lr)r=lr[e],i=n[r],p(i)||(t[r]=i);return t}function y(t){g(this,t),this._d=new Date(null!=t._d?t._d.getTime():0/0),hr===!1&&(hr=!0,e.updateOffset(this),hr=!1)}function m(t){return t instanceof y||null!=t&&null!=t._isAMomentObject}function v(t){return 0>t?Math.ceil(t):Math.floor(t)}function _(t){var n=+t,e=0;return 0!==n&&isFinite(n)&&(e=v(n)),e}function b(t,n,e){var r,i=Math.min(t.length,n.length),a=Math.abs(t.length-n.length),u=0;for(r=0;i>r;r++)(e&&t[r]!==n[r]||!e&&_(t[r])!==_(n[r]))&&u++;return u+a}function x(t){e.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+t)}function w(t,n){var r=!0;return s(function(){return null!=e.deprecationHandler&&e.deprecationHandler(null,t),r&&(x(t+"\nArguments: "+Array.prototype.slice.call(arguments).join(", ")+"\n"+(new Error).stack),r=!1),n.apply(this,arguments)},n)}function A(t,n){null!=e.deprecationHandler&&e.deprecationHandler(t,n),fr[t]||(x(n),fr[t]=!0)}function k(t){return t instanceof Function||"[object Function]"===Object.prototype.toString.call(t)}function E(t){return"[object Object]"===Object.prototype.toString.call(t)}function M(t){var n,e;for(e in t)n=t[e],k(n)?this[e]=n:this["_"+e]=n;this._config=t,this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)}function S(t,n){var e,r=s({},t);for(e in n)o(n,e)&&(E(t[e])&&E(n[e])?(r[e]={},s(r[e],t[e]),s(r[e],n[e])):null!=n[e]?r[e]=n[e]:delete r[e]);return r}function D(t){null!=t&&this.set(t)}function C(t){return t?t.toLowerCase().replace("_","-"):t}function T(t){for(var n,e,r,i,a=0;a0;){if(r=F(i.slice(0,n).join("-")))return r;if(e&&e.length>=n&&b(i,e,!0)>=n-1)break;n--}a++}return null}function F(e){var r=null;if(!yr[e]&&"undefined"!=typeof n&&n&&n.exports)try{r=pr._abbr,t("./locale/"+e),O(r)}catch(i){}return yr[e]}function O(t,n){var e;return t&&(e=p(n)?B(t):L(t,n),e&&(pr=e)),pr._abbr}function L(t,n){return null!==n?(n.abbr=t,null!=yr[t]?(A("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale"),n=S(yr[t]._config,n)):null!=n.parentLocale&&(null!=yr[n.parentLocale]?n=S(yr[n.parentLocale]._config,n):A("parentLocaleUndefined","specified parentLocale is not defined yet")),yr[t]=new D(n),O(t),yr[t]):(delete yr[t],null)}function I(t,n){if(null!=n){var e;null!=yr[t]&&(n=S(yr[t]._config,n)),e=new D(n),e.parentLocale=yr[t],yr[t]=e,O(t)}else null!=yr[t]&&(null!=yr[t].parentLocale?yr[t]=yr[t].parentLocale:null!=yr[t]&&delete yr[t]);return yr[t]}function B(t){var n;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return pr;if(!i(t)){if(n=F(t))return n;t=[t]}return T(t)}function N(){return dr(yr)}function P(t,n){var e=t.toLowerCase();mr[e]=mr[e+"s"]=mr[n]=t}function R(t){return"string"==typeof t?mr[t]||mr[t.toLowerCase()]:void 0}function j(t){var n,e,r={};for(e in t)o(t,e)&&(n=R(e),n&&(r[n]=t[e]));return r}function Y(t,n){return function(r){return null!=r?($(this,t,r),e.updateOffset(this,n),this):U(this,t)}}function U(t,n){return t.isValid()?t._d["get"+(t._isUTC?"UTC":"")+n]():0/0}function $(t,n,e){t.isValid()&&t._d["set"+(t._isUTC?"UTC":"")+n](e)}function W(t,n){var e;if("object"==typeof t)for(e in t)this.set(e,t[e]);else if(t=R(t),k(this[t]))return this[t](n);return this}function z(t,n,e){var r=""+Math.abs(t),i=n-r.length,a=t>=0;return(a?e?"+":"":"-")+Math.pow(10,Math.max(0,i)).toString().substr(1)+r}function q(t,n,e,r){var i=r;"string"==typeof r&&(i=function(){return this[r]()}),t&&(xr[t]=i),n&&(xr[n[0]]=function(){return z(i.apply(this,arguments),n[1],n[2])}),e&&(xr[e]=function(){return this.localeData().ordinal(i.apply(this,arguments),t)})}function G(t){return t.match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"")}function H(t){var n,e,r=t.match(vr);for(n=0,e=r.length;e>n;n++)r[n]=xr[r[n]]?xr[r[n]]:G(r[n]);return function(n){var i,a="";for(i=0;e>i;i++)a+=r[i]instanceof Function?r[i].call(n,t):r[i];return a}}function V(t,n){return t.isValid()?(n=Z(n,t.localeData()),br[n]=br[n]||H(n),br[n](t)):t.localeData().invalidDate()}function Z(t,n){function e(t){return n.longDateFormat(t)||t}var r=5;for(_r.lastIndex=0;r>=0&&_r.test(t);)t=t.replace(_r,e),_r.lastIndex=0,r-=1;return t}function X(t,n,e){jr[t]=k(n)?n:function(t){return t&&e?e:n}}function K(t,n){return o(jr,t)?jr[t](n._strict,n._locale):new RegExp(Q(t))}function Q(t){return J(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(t,n,e,r,i){return n||e||r||i}))}function J(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function tt(t,n){var e,r=n;for("string"==typeof t&&(t=[t]),"number"==typeof n&&(r=function(t,e){e[n]=_(t)}),e=0;er;++r)a=c([2e3,r]),this._shortMonthsParse[r]=this.monthsShort(a,"").toLocaleLowerCase(),this._longMonthsParse[r]=this.months(a,"").toLocaleLowerCase();return e?"MMM"===n?(i=gr.call(this._shortMonthsParse,u),-1!==i?i:null):(i=gr.call(this._longMonthsParse,u),-1!==i?i:null):"MMM"===n?(i=gr.call(this._shortMonthsParse,u),-1!==i?i:(i=gr.call(this._longMonthsParse,u),-1!==i?i:null)):(i=gr.call(this._longMonthsParse,u),-1!==i?i:(i=gr.call(this._shortMonthsParse,u),-1!==i?i:null))}function ot(t,n,e){var r,i,a;if(this._monthsParseExact)return ut.call(this,t,n,e);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),r=0;12>r;r++){if(i=c([2e3,r]),e&&!this._longMonthsParse[r]&&(this._longMonthsParse[r]=new RegExp("^"+this.months(i,"").replace(".","")+"$","i"),this._shortMonthsParse[r]=new RegExp("^"+this.monthsShort(i,"").replace(".","")+"$","i")),e||this._monthsParse[r]||(a="^"+this.months(i,"")+"|^"+this.monthsShort(i,""),this._monthsParse[r]=new RegExp(a.replace(".",""),"i")),e&&"MMMM"===n&&this._longMonthsParse[r].test(t))return r;if(e&&"MMM"===n&&this._shortMonthsParse[r].test(t))return r;if(!e&&this._monthsParse[r].test(t))return r}}function st(t,n){var e;if(!t.isValid())return t;if("string"==typeof n)if(/^\d+$/.test(n))n=_(n);else if(n=t.localeData().monthsParse(n),"number"!=typeof n)return t;return e=Math.min(t.date(),rt(t.year(),n)),t._d["set"+(t._isUTC?"UTC":"")+"Month"](n,e),t}function ct(t){return null!=t?(st(this,t),e.updateOffset(this,!0),this):U(this,"Month")}function lt(){return rt(this.year(),this.month())}function ht(t){return this._monthsParseExact?(o(this,"_monthsRegex")||dt.call(this),t?this._monthsShortStrictRegex:this._monthsShortRegex):this._monthsShortStrictRegex&&t?this._monthsShortStrictRegex:this._monthsShortRegex}function ft(t){return this._monthsParseExact?(o(this,"_monthsRegex")||dt.call(this),t?this._monthsStrictRegex:this._monthsRegex):this._monthsStrictRegex&&t?this._monthsStrictRegex:this._monthsRegex}function dt(){function t(t,n){return n.length-t.length}var n,e,r=[],i=[],a=[];for(n=0;12>n;n++)e=c([2e3,n]),r.push(this.monthsShort(e,"")),i.push(this.months(e,"")),a.push(this.months(e,"")),a.push(this.monthsShort(e,""));for(r.sort(t),i.sort(t),a.sort(t),n=0;12>n;n++)r[n]=J(r[n]),i[n]=J(i[n]),a[n]=J(a[n]);this._monthsRegex=new RegExp("^("+a.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+r.join("|")+")","i")}function pt(t){var n,e=t._a;return e&&-2===h(t).overflow&&(n=e[$r]<0||e[$r]>11?$r:e[Wr]<1||e[Wr]>rt(e[Ur],e[$r])?Wr:e[zr]<0||e[zr]>24||24===e[zr]&&(0!==e[qr]||0!==e[Gr]||0!==e[Hr])?zr:e[qr]<0||e[qr]>59?qr:e[Gr]<0||e[Gr]>59?Gr:e[Hr]<0||e[Hr]>999?Hr:-1,h(t)._overflowDayOfYear&&(Ur>n||n>Wr)&&(n=Wr),h(t)._overflowWeeks&&-1===n&&(n=Vr),h(t)._overflowWeekday&&-1===n&&(n=Zr),h(t).overflow=n),t}function gt(t){var n,e,r,i,a,u,o=t._i,s=ni.exec(o)||ei.exec(o);if(s){for(h(t).iso=!0,n=0,e=ii.length;e>n;n++)if(ii[n][1].exec(s[1])){i=ii[n][0],r=ii[n][2]!==!1;break}if(null==i)return void(t._isValid=!1);if(s[3]){for(n=0,e=ai.length;e>n;n++)if(ai[n][1].exec(s[3])){a=(s[2]||" ")+ai[n][0];break}if(null==a)return void(t._isValid=!1)}if(!r&&null!=a)return void(t._isValid=!1);if(s[4]){if(!ri.exec(s[4]))return void(t._isValid=!1);u="Z"}t._f=i+(a||"")+(u||""),Tt(t)}else t._isValid=!1}function yt(t){var n=ui.exec(t._i);return null!==n?void(t._d=new Date(+n[1])):(gt(t),void(t._isValid===!1&&(delete t._isValid,e.createFromInputFallback(t))))}function mt(t,n,e,r,i,a,u){var o=new Date(t,n,e,r,i,a,u);return 100>t&&t>=0&&isFinite(o.getFullYear())&&o.setFullYear(t),o}function vt(t){var n=new Date(Date.UTC.apply(null,arguments));return 100>t&&t>=0&&isFinite(n.getUTCFullYear())&&n.setUTCFullYear(t),n}function _t(t){return bt(t)?366:365}function bt(t){return t%4===0&&t%100!==0||t%400===0}function xt(){return bt(this.year())}function wt(t,n,e){var r=7+n-e,i=(7+vt(t,0,r).getUTCDay()-n)%7;return-i+r-1}function At(t,n,e,r,i){var a,u,o=(7+e-r)%7,s=wt(t,r,i),c=1+7*(n-1)+o+s;return 0>=c?(a=t-1,u=_t(a)+c):c>_t(t)?(a=t+1,u=c-_t(t)):(a=t,u=c),{year:a,dayOfYear:u}}function kt(t,n,e){var r,i,a=wt(t.year(),n,e),u=Math.floor((t.dayOfYear()-a-1)/7)+1;return 1>u?(i=t.year()-1,r=u+Et(i,n,e)):u>Et(t.year(),n,e)?(r=u-Et(t.year(),n,e),i=t.year()+1):(i=t.year(),r=u),{week:r,year:i}}function Et(t,n,e){var r=wt(t,n,e),i=wt(t+1,n,e);return(_t(t)-r+i)/7}function Mt(t,n,e){return null!=t?t:null!=n?n:e}function St(t){var n=new Date(e.now());return t._useUTC?[n.getUTCFullYear(),n.getUTCMonth(),n.getUTCDate()]:[n.getFullYear(),n.getMonth(),n.getDate()]}function Dt(t){var n,e,r,i,a=[];if(!t._d){for(r=St(t),t._w&&null==t._a[Wr]&&null==t._a[$r]&&Ct(t),t._dayOfYear&&(i=Mt(t._a[Ur],r[Ur]),t._dayOfYear>_t(i)&&(h(t)._overflowDayOfYear=!0),e=vt(i,0,t._dayOfYear),t._a[$r]=e.getUTCMonth(),t._a[Wr]=e.getUTCDate()),n=0;3>n&&null==t._a[n];++n)t._a[n]=a[n]=r[n];for(;7>n;n++)t._a[n]=a[n]=null==t._a[n]?2===n?1:0:t._a[n];24===t._a[zr]&&0===t._a[qr]&&0===t._a[Gr]&&0===t._a[Hr]&&(t._nextDay=!0,t._a[zr]=0),t._d=(t._useUTC?vt:mt).apply(null,a),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[zr]=24)}}function Ct(t){var n,e,r,i,a,u,o,s;n=t._w,null!=n.GG||null!=n.W||null!=n.E?(a=1,u=4,e=Mt(n.GG,t._a[Ur],kt(Rt(),1,4).year),r=Mt(n.W,1),i=Mt(n.E,1),(1>i||i>7)&&(s=!0)):(a=t._locale._week.dow,u=t._locale._week.doy,e=Mt(n.gg,t._a[Ur],kt(Rt(),a,u).year),r=Mt(n.w,1),null!=n.d?(i=n.d,(0>i||i>6)&&(s=!0)):null!=n.e?(i=n.e+a,(n.e<0||n.e>6)&&(s=!0)):i=a),1>r||r>Et(e,a,u)?h(t)._overflowWeeks=!0:null!=s?h(t)._overflowWeekday=!0:(o=At(e,r,i,a,u),t._a[Ur]=o.year,t._dayOfYear=o.dayOfYear)}function Tt(t){if(t._f===e.ISO_8601)return void gt(t);t._a=[],h(t).empty=!0;var n,r,i,a,u,o=""+t._i,s=o.length,c=0;for(i=Z(t._f,t._locale).match(vr)||[],n=0;n0&&h(t).unusedInput.push(u),o=o.slice(o.indexOf(r)+r.length),c+=r.length),xr[a]?(r?h(t).empty=!1:h(t).unusedTokens.push(a),et(a,r,t)):t._strict&&!r&&h(t).unusedTokens.push(a);h(t).charsLeftOver=s-c,o.length>0&&h(t).unusedInput.push(o),h(t).bigHour===!0&&t._a[zr]<=12&&t._a[zr]>0&&(h(t).bigHour=void 0),h(t).parsedDateParts=t._a.slice(0),h(t).meridiem=t._meridiem,t._a[zr]=Ft(t._locale,t._a[zr],t._meridiem),Dt(t),pt(t)}function Ft(t,n,e){var r;return null==e?n:null!=t.meridiemHour?t.meridiemHour(n,e):null!=t.isPM?(r=t.isPM(e),r&&12>n&&(n+=12),r||12!==n||(n=0),n):n}function Ot(t){var n,e,r,i,a;if(0===t._f.length)return h(t).invalidFormat=!0,void(t._d=new Date(0/0));for(i=0;ia)&&(r=a,e=n));s(t,e||n)}function Lt(t){if(!t._d){var n=j(t._i);t._a=u([n.year,n.month,n.day||n.date,n.hour,n.minute,n.second,n.millisecond],function(t){return t&&parseInt(t,10)}),Dt(t)}}function It(t){var n=new y(pt(Bt(t)));return n._nextDay&&(n.add(1,"d"),n._nextDay=void 0),n}function Bt(t){var n=t._i,e=t._f;return t._locale=t._locale||B(t._l),null===n||void 0===e&&""===n?d({nullInput:!0}):("string"==typeof n&&(t._i=n=t._locale.preparse(n)),m(n)?new y(pt(n)):(i(e)?Ot(t):e?Tt(t):a(n)?t._d=n:Nt(t),f(t)||(t._d=null),t))}function Nt(t){var n=t._i;void 0===n?t._d=new Date(e.now()):a(n)?t._d=new Date(n.valueOf()):"string"==typeof n?yt(t):i(n)?(t._a=u(n.slice(0),function(t){return parseInt(t,10)}),Dt(t)):"object"==typeof n?Lt(t):"number"==typeof n?t._d=new Date(n):e.createFromInputFallback(t)}function Pt(t,n,e,r,i){var a={};return"boolean"==typeof e&&(r=e,e=void 0),a._isAMomentObject=!0,a._useUTC=a._isUTC=i,a._l=e,a._i=t,a._f=n,a._strict=r,It(a)}function Rt(t,n,e,r){return Pt(t,n,e,r,!1)}function jt(t,n){var e,r;if(1===n.length&&i(n[0])&&(n=n[0]),!n.length)return Rt();for(e=n[0],r=1;rt&&(t=-t,e="-"),e+z(~~(t/60),2)+n+z(~~t%60,2)})}function qt(t,n){var e=(n||"").match(t)||[],r=e[e.length-1]||[],i=(r+"").match(hi)||["-",0,0],a=+(60*i[1])+_(i[2]);return"+"===i[0]?a:-a}function Gt(t,n){var r,i;return n._isUTC?(r=n.clone(),i=(m(t)||a(t)?t.valueOf():Rt(t).valueOf())-r.valueOf(),r._d.setTime(r._d.valueOf()+i),e.updateOffset(r,!1),r):Rt(t).local()}function Ht(t){return 15*-Math.round(t._d.getTimezoneOffset()/15)}function Vt(t,n){var r,i=this._offset||0;return this.isValid()?null!=t?("string"==typeof t?t=qt(Nr,t):Math.abs(t)<16&&(t=60*t),!this._isUTC&&n&&(r=Ht(this)),this._offset=t,this._isUTC=!0,null!=r&&this.add(r,"m"),i!==t&&(!n||this._changeInProgress?fn(this,un(t-i,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,e.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?i:Ht(this):null!=t?this:0/0}function Zt(t,n){return null!=t?("string"!=typeof t&&(t=-t),this.utcOffset(t,n),this):-this.utcOffset()}function Xt(t){return this.utcOffset(0,t)}function Kt(t){return this._isUTC&&(this.utcOffset(0,t),this._isUTC=!1,t&&this.subtract(Ht(this),"m")),this}function Qt(){return this._tzm?this.utcOffset(this._tzm):"string"==typeof this._i&&this.utcOffset(qt(Br,this._i)),this}function Jt(t){return this.isValid()?(t=t?Rt(t).utcOffset():0,(this.utcOffset()-t)%60===0):!1}function tn(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function nn(){if(!p(this._isDSTShifted))return this._isDSTShifted;var t={};if(g(t,this),t=Bt(t),t._a){var n=t._isUTC?c(t._a):Rt(t._a);this._isDSTShifted=this.isValid()&&b(t._a,n.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function en(){return this.isValid()?!this._isUTC:!1}function rn(){return this.isValid()?this._isUTC:!1}function an(){return this.isValid()?this._isUTC&&0===this._offset:!1}function un(t,n){var e,r,i,a=t,u=null;return Wt(t)?a={ms:t._milliseconds,d:t._days,M:t._months}:"number"==typeof t?(a={},n?a[n]=t:a.milliseconds=t):(u=fi.exec(t))?(e="-"===u[1]?-1:1,a={y:0,d:_(u[Wr])*e,h:_(u[zr])*e,m:_(u[qr])*e,s:_(u[Gr])*e,ms:_(u[Hr])*e}):(u=di.exec(t))?(e="-"===u[1]?-1:1,a={y:on(u[2],e),M:on(u[3],e),w:on(u[4],e),d:on(u[5],e),h:on(u[6],e),m:on(u[7],e),s:on(u[8],e)}):null==a?a={}:"object"==typeof a&&("from"in a||"to"in a)&&(i=cn(Rt(a.from),Rt(a.to)),a={},a.ms=i.milliseconds,a.M=i.months),r=new $t(a),Wt(t)&&o(t,"_locale")&&(r._locale=t._locale),r}function on(t,n){var e=t&&parseFloat(t.replace(",","."));return(isNaN(e)?0:e)*n}function sn(t,n){var e={milliseconds:0,months:0};return e.months=n.month()-t.month()+12*(n.year()-t.year()),t.clone().add(e.months,"M").isAfter(n)&&--e.months,e.milliseconds=+n-+t.clone().add(e.months,"M"),e}function cn(t,n){var e;return t.isValid()&&n.isValid()?(n=Gt(n,t),t.isBefore(n)?e=sn(t,n):(e=sn(n,t),e.milliseconds=-e.milliseconds,e.months=-e.months),e):{milliseconds:0,months:0}}function ln(t){return 0>t?-1*Math.round(-1*t):Math.round(t)}function hn(t,n){return function(e,r){var i,a;return null===r||isNaN(+r)||(A(n,"moment()."+n+"(period, number) is deprecated. Please use moment()."+n+"(number, period)."), -a=e,e=r,r=a),e="string"==typeof e?+e:e,i=un(e,r),fn(this,i,t),this}}function fn(t,n,r,i){var a=n._milliseconds,u=ln(n._days),o=ln(n._months);t.isValid()&&(i=null==i?!0:i,a&&t._d.setTime(t._d.valueOf()+a*r),u&&$(t,"Date",U(t,"Date")+u*r),o&&st(t,U(t,"Month")+o*r),i&&e.updateOffset(t,u||o))}function dn(t,n){var e=t||Rt(),r=Gt(e,this).startOf("day"),i=this.diff(r,"days",!0),a=-6>i?"sameElse":-1>i?"lastWeek":0>i?"lastDay":1>i?"sameDay":2>i?"nextDay":7>i?"nextWeek":"sameElse",u=n&&(k(n[a])?n[a]():n[a]);return this.format(u||this.localeData().calendar(a,this,Rt(e)))}function pn(){return new y(this)}function gn(t,n){var e=m(t)?t:Rt(t);return this.isValid()&&e.isValid()?(n=R(p(n)?"millisecond":n),"millisecond"===n?this.valueOf()>e.valueOf():e.valueOf()n-a?(e=t.clone().add(i-1,"months"),r=(n-a)/(a-e)):(e=t.clone().add(i+1,"months"),r=(n-a)/(e-a)),-(i+r)||0}function An(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function kn(){var t=this.clone().utc();return 0a&&(n=a),Xn.call(this,t,n,e,r,i))}function Xn(t,n,e,r,i){var a=At(t,n,e,r,i),u=vt(a.year,0,a.dayOfYear);return this.year(u.getUTCFullYear()),this.month(u.getUTCMonth()),this.date(u.getUTCDate()),this}function Kn(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)}function Qn(t){return kt(t,this._week.dow,this._week.doy).week}function Jn(){return this._week.dow}function te(){return this._week.doy}function ne(t){var n=this.localeData().week(this);return null==t?n:this.add(7*(t-n),"d")}function ee(t){var n=kt(this,1,4).week;return null==t?n:this.add(7*(t-n),"d")}function re(t,n){return"string"!=typeof t?t:isNaN(t)?(t=n.weekdaysParse(t),"number"==typeof t?t:null):parseInt(t,10)}function ie(t,n){return i(this._weekdays)?this._weekdays[t.day()]:this._weekdays[this._weekdays.isFormat.test(n)?"format":"standalone"][t.day()]}function ae(t){return this._weekdaysShort[t.day()]}function ue(t){return this._weekdaysMin[t.day()]}function oe(t,n,e){var r,i,a,u=t.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],r=0;7>r;++r)a=c([2e3,1]).day(r),this._minWeekdaysParse[r]=this.weekdaysMin(a,"").toLocaleLowerCase(),this._shortWeekdaysParse[r]=this.weekdaysShort(a,"").toLocaleLowerCase(),this._weekdaysParse[r]=this.weekdays(a,"").toLocaleLowerCase();return e?"dddd"===n?(i=gr.call(this._weekdaysParse,u),-1!==i?i:null):"ddd"===n?(i=gr.call(this._shortWeekdaysParse,u),-1!==i?i:null):(i=gr.call(this._minWeekdaysParse,u),-1!==i?i:null):"dddd"===n?(i=gr.call(this._weekdaysParse,u),-1!==i?i:(i=gr.call(this._shortWeekdaysParse,u),-1!==i?i:(i=gr.call(this._minWeekdaysParse,u),-1!==i?i:null))):"ddd"===n?(i=gr.call(this._shortWeekdaysParse,u),-1!==i?i:(i=gr.call(this._weekdaysParse,u),-1!==i?i:(i=gr.call(this._minWeekdaysParse,u),-1!==i?i:null))):(i=gr.call(this._minWeekdaysParse,u),-1!==i?i:(i=gr.call(this._weekdaysParse,u),-1!==i?i:(i=gr.call(this._shortWeekdaysParse,u),-1!==i?i:null)))}function se(t,n,e){var r,i,a;if(this._weekdaysParseExact)return oe.call(this,t,n,e);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),r=0;7>r;r++){if(i=c([2e3,1]).day(r),e&&!this._fullWeekdaysParse[r]&&(this._fullWeekdaysParse[r]=new RegExp("^"+this.weekdays(i,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[r]=new RegExp("^"+this.weekdaysShort(i,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[r]=new RegExp("^"+this.weekdaysMin(i,"").replace(".",".?")+"$","i")),this._weekdaysParse[r]||(a="^"+this.weekdays(i,"")+"|^"+this.weekdaysShort(i,"")+"|^"+this.weekdaysMin(i,""),this._weekdaysParse[r]=new RegExp(a.replace(".",""),"i")),e&&"dddd"===n&&this._fullWeekdaysParse[r].test(t))return r;if(e&&"ddd"===n&&this._shortWeekdaysParse[r].test(t))return r;if(e&&"dd"===n&&this._minWeekdaysParse[r].test(t))return r;if(!e&&this._weekdaysParse[r].test(t))return r}}function ce(t){if(!this.isValid())return null!=t?this:0/0;var n=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=t?(t=re(t,this.localeData()),this.add(t-n,"d")):n}function le(t){if(!this.isValid())return null!=t?this:0/0;var n=(this.day()+7-this.localeData()._week.dow)%7;return null==t?n:this.add(t-n,"d")}function he(t){return this.isValid()?null==t?this.day()||7:this.day(this.day()%7?t:t-7):null!=t?this:0/0}function fe(t){return this._weekdaysParseExact?(o(this,"_weekdaysRegex")||ge.call(this),t?this._weekdaysStrictRegex:this._weekdaysRegex):this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex}function de(t){return this._weekdaysParseExact?(o(this,"_weekdaysRegex")||ge.call(this),t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex}function pe(t){return this._weekdaysParseExact?(o(this,"_weekdaysRegex")||ge.call(this),t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex}function ge(){function t(t,n){return n.length-t.length}var n,e,r,i,a,u=[],o=[],s=[],l=[];for(n=0;7>n;n++)e=c([2e3,1]).day(n),r=this.weekdaysMin(e,""),i=this.weekdaysShort(e,""),a=this.weekdays(e,""),u.push(r),o.push(i),s.push(a),l.push(r),l.push(i),l.push(a);for(u.sort(t),o.sort(t),s.sort(t),l.sort(t),n=0;7>n;n++)o[n]=J(o[n]),s[n]=J(s[n]),l[n]=J(l[n]);this._weekdaysRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+u.join("|")+")","i")}function ye(t){var n=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==t?n:this.add(t-n,"d")}function me(){return this.hours()%12||12}function ve(){return this.hours()||24}function _e(t,n){q(t,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),n)})}function be(t,n){return n._meridiemParse}function xe(t){return"p"===(t+"").toLowerCase().charAt(0)}function we(t,n,e){return t>11?e?"pm":"PM":e?"am":"AM"}function Ae(t,n){n[Hr]=_(1e3*("0."+t))}function ke(){return this._isUTC?"UTC":""}function Ee(){return this._isUTC?"Coordinated Universal Time":""}function Me(t){return Rt(1e3*t)}function Se(){return Rt.apply(null,arguments).parseZone()}function De(t,n,e){var r=this._calendar[t];return k(r)?r.call(n,e):r}function Ce(t){var n=this._longDateFormat[t],e=this._longDateFormat[t.toUpperCase()];return n||!e?n:(this._longDateFormat[t]=e.replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)}),this._longDateFormat[t])}function Te(){return this._invalidDate}function Fe(t){return this._ordinal.replace("%d",t)}function Oe(t){return t}function Le(t,n,e,r){var i=this._relativeTime[e];return k(i)?i(t,n,e,r):i.replace(/%d/i,t)}function Ie(t,n){var e=this._relativeTime[t>0?"future":"past"];return k(e)?e(n):e.replace(/%s/i,n)}function Be(t,n,e,r){var i=B(),a=c().set(r,n);return i[e](a,t)}function Ne(t,n,e){if("number"==typeof t&&(n=t,t=void 0),t=t||"",null!=n)return Be(t,n,e,"month");var r,i=[];for(r=0;12>r;r++)i[r]=Be(t,r,e,"month");return i}function Pe(t,n,e,r){"boolean"==typeof t?("number"==typeof n&&(e=n,n=void 0),n=n||""):(n=t,e=n,t=!1,"number"==typeof n&&(e=n,n=void 0),n=n||"");var i=B(),a=t?i._week.dow:0;if(null!=e)return Be(n,(e+a)%7,r,"day");var u,o=[];for(u=0;7>u;u++)o[u]=Be(n,(u+a)%7,r,"day");return o}function Re(t,n){return Ne(t,n,"months")}function je(t,n){return Ne(t,n,"monthsShort")}function Ye(t,n,e){return Pe(t,n,e,"weekdays")}function Ue(t,n,e){return Pe(t,n,e,"weekdaysShort")}function $e(t,n,e){return Pe(t,n,e,"weekdaysMin")}function We(){var t=this._data;return this._milliseconds=Yi(this._milliseconds),this._days=Yi(this._days),this._months=Yi(this._months),t.milliseconds=Yi(t.milliseconds),t.seconds=Yi(t.seconds),t.minutes=Yi(t.minutes),t.hours=Yi(t.hours),t.months=Yi(t.months),t.years=Yi(t.years),this}function ze(t,n,e,r){var i=un(n,e);return t._milliseconds+=r*i._milliseconds,t._days+=r*i._days,t._months+=r*i._months,t._bubble()}function qe(t,n){return ze(this,t,n,1)}function Ge(t,n){return ze(this,t,n,-1)}function He(t){return 0>t?Math.floor(t):Math.ceil(t)}function Ve(){var t,n,e,r,i,a=this._milliseconds,u=this._days,o=this._months,s=this._data;return a>=0&&u>=0&&o>=0||0>=a&&0>=u&&0>=o||(a+=864e5*He(Xe(o)+u),u=0,o=0),s.milliseconds=a%1e3,t=v(a/1e3),s.seconds=t%60,n=v(t/60),s.minutes=n%60,e=v(n/60),s.hours=e%24,u+=v(e/24),i=v(Ze(u)),o+=i,u-=He(Xe(i)),r=v(o/12),o%=12,s.days=u,s.months=o,s.years=r,this}function Ze(t){return 4800*t/146097}function Xe(t){return 146097*t/4800}function Ke(t){var n,e,r=this._milliseconds;if(t=R(t),"month"===t||"year"===t)return n=this._days+r/864e5,e=this._months+Ze(n),"month"===t?e:e/12;switch(n=this._days+Math.round(Xe(this._months)),t){case"week":return n/7+r/6048e5;case"day":return n+r/864e5;case"hour":return 24*n+r/36e5;case"minute":return 1440*n+r/6e4;case"second":return 86400*n+r/1e3;case"millisecond":return Math.floor(864e5*n)+r;default:throw new Error("Unknown unit "+t)}}function Qe(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*_(this._months/12)}function Je(t){return function(){return this.as(t)}}function tr(t){return t=R(t),this[t+"s"]()}function nr(t){return function(){return this._data[t]}}function er(){return v(this.days()/7)}function rr(t,n,e,r,i){return i.relativeTime(n||1,!!e,t,r)}function ir(t,n,e){var r=un(t).abs(),i=ea(r.as("s")),a=ea(r.as("m")),u=ea(r.as("h")),o=ea(r.as("d")),s=ea(r.as("M")),c=ea(r.as("y")),l=i=a&&["m"]||a=u&&["h"]||u=o&&["d"]||o=s&&["M"]||s=c&&["y"]||["yy",c];return l[2]=n,l[3]=+t>0,l[4]=e,rr.apply(null,l)}function ar(t,n){return void 0===ra[t]?!1:void 0===n?ra[t]:(ra[t]=n,!0)}function ur(t){var n=this.localeData(),e=ir(this,!t,n);return t&&(e=n.pastFuture(+this,e)),n.postformat(e)}function or(){var t,n,e,r=ia(this._milliseconds)/1e3,i=ia(this._days),a=ia(this._months);t=v(r/60),n=v(t/60),r%=60,t%=60,e=v(a/12),a%=12;var u=e,o=a,s=i,c=n,l=t,h=r,f=this.asSeconds();return f?(0>f?"-":"")+"P"+(u?u+"Y":"")+(o?o+"M":"")+(s?s+"D":"")+(c||l||h?"T":"")+(c?c+"H":"")+(l?l+"M":"")+(h?h+"S":""):"P0D"}var sr,cr;cr=Array.prototype.some?Array.prototype.some:function(t){for(var n=Object(this),e=n.length>>>0,r=0;e>r;r++)if(r in n&&t.call(this,n[r],r,n))return!0;return!1};var lr=e.momentProperties=[],hr=!1,fr={};e.suppressDeprecationWarnings=!1,e.deprecationHandler=null;var dr;dr=Object.keys?Object.keys:function(t){var n,e=[];for(n in t)o(t,n)&&e.push(n);return e};var pr,gr,yr={},mr={},vr=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,_r=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,br={},xr={},wr=/\d/,Ar=/\d\d/,kr=/\d{3}/,Er=/\d{4}/,Mr=/[+-]?\d{6}/,Sr=/\d\d?/,Dr=/\d\d\d\d?/,Cr=/\d\d\d\d\d\d?/,Tr=/\d{1,3}/,Fr=/\d{1,4}/,Or=/[+-]?\d{1,6}/,Lr=/\d+/,Ir=/[+-]?\d+/,Br=/Z|[+-]\d\d:?\d\d/gi,Nr=/Z|[+-]\d\d(?::?\d\d)?/gi,Pr=/[+-]?\d+(\.\d{1,3})?/,Rr=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,jr={},Yr={},Ur=0,$r=1,Wr=2,zr=3,qr=4,Gr=5,Hr=6,Vr=7,Zr=8;gr=Array.prototype.indexOf?Array.prototype.indexOf:function(t){var n;for(n=0;n=t?""+t:"+"+t}),q(0,["YY",2],0,function(){return this.year()%100}),q(0,["YYYY",4],0,"year"),q(0,["YYYYY",5],0,"year"),q(0,["YYYYYY",6,!0],0,"year"),P("year","y"),X("Y",Ir),X("YY",Sr,Ar),X("YYYY",Fr,Er),X("YYYYY",Or,Mr),X("YYYYYY",Or,Mr),tt(["YYYYY","YYYYYY"],Ur),tt("YYYY",function(t,n){n[Ur]=2===t.length?e.parseTwoDigitYear(t):_(t)}),tt("YY",function(t,n){n[Ur]=e.parseTwoDigitYear(t)}),tt("Y",function(t,n){n[Ur]=parseInt(t,10)}),e.parseTwoDigitYear=function(t){return _(t)+(_(t)>68?1900:2e3)};var oi=Y("FullYear",!0);e.ISO_8601=function(){};var si=w("moment().min is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(){var t=Rt.apply(null,arguments);return this.isValid()&&t.isValid()?this>t?this:t:d()}),ci=w("moment().max is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(){var t=Rt.apply(null,arguments);return this.isValid()&&t.isValid()?t>this?this:t:d()}),li=function(){return Date.now?Date.now():+new Date};zt("Z",":"),zt("ZZ",""),X("Z",Nr),X("ZZ",Nr),tt(["Z","ZZ"],function(t,n,e){e._useUTC=!0,e._tzm=qt(Nr,t)});var hi=/([\+\-]|\d\d)/gi;e.updateOffset=function(){};var fi=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?\d*)?$/,di=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;un.fn=$t.prototype;var pi=hn(1,"add"),gi=hn(-1,"subtract");e.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",e.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var yi=w("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(t){return void 0===t?this.localeData():this.locale(t)});q(0,["gg",2],0,function(){return this.weekYear()%100}),q(0,["GG",2],0,function(){return this.isoWeekYear()%100}),zn("gggg","weekYear"),zn("ggggg","weekYear"),zn("GGGG","isoWeekYear"),zn("GGGGG","isoWeekYear"),P("weekYear","gg"),P("isoWeekYear","GG"),X("G",Ir),X("g",Ir),X("GG",Sr,Ar),X("gg",Sr,Ar),X("GGGG",Fr,Er),X("gggg",Fr,Er),X("GGGGG",Or,Mr),X("ggggg",Or,Mr),nt(["gggg","ggggg","GGGG","GGGGG"],function(t,n,e,r){n[r.substr(0,2)]=_(t)}),nt(["gg","GG"],function(t,n,r,i){n[i]=e.parseTwoDigitYear(t)}),q("Q",0,"Qo","quarter"),P("quarter","Q"),X("Q",wr),tt("Q",function(t,n){n[$r]=3*(_(t)-1)}),q("w",["ww",2],"wo","week"),q("W",["WW",2],"Wo","isoWeek"),P("week","w"),P("isoWeek","W"),X("w",Sr),X("ww",Sr,Ar),X("W",Sr),X("WW",Sr,Ar),nt(["w","ww","W","WW"],function(t,n,e,r){n[r.substr(0,1)]=_(t)});var mi={dow:0,doy:6};q("D",["DD",2],"Do","date"),P("date","D"),X("D",Sr),X("DD",Sr,Ar),X("Do",function(t,n){return t?n._ordinalParse:n._ordinalParseLenient}),tt(["D","DD"],Wr),tt("Do",function(t,n){n[Wr]=_(t.match(Sr)[0],10)});var vi=Y("Date",!0);q("d",0,"do","day"),q("dd",0,0,function(t){return this.localeData().weekdaysMin(this,t)}),q("ddd",0,0,function(t){return this.localeData().weekdaysShort(this,t)}),q("dddd",0,0,function(t){return this.localeData().weekdays(this,t)}),q("e",0,0,"weekday"),q("E",0,0,"isoWeekday"),P("day","d"),P("weekday","e"),P("isoWeekday","E"),X("d",Sr),X("e",Sr),X("E",Sr),X("dd",function(t,n){return n.weekdaysMinRegex(t)}),X("ddd",function(t,n){return n.weekdaysShortRegex(t)}),X("dddd",function(t,n){return n.weekdaysRegex(t)}),nt(["dd","ddd","dddd"],function(t,n,e,r){var i=e._locale.weekdaysParse(t,r,e._strict);null!=i?n.d=i:h(e).invalidWeekday=t}),nt(["d","e","E"],function(t,n,e,r){n[r]=_(t)});var _i="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),bi="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),xi="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),wi=Rr,Ai=Rr,ki=Rr;q("DDD",["DDDD",3],"DDDo","dayOfYear"),P("dayOfYear","DDD"),X("DDD",Tr),X("DDDD",kr),tt(["DDD","DDDD"],function(t,n,e){e._dayOfYear=_(t)}),q("H",["HH",2],0,"hour"),q("h",["hh",2],0,me),q("k",["kk",2],0,ve),q("hmm",0,0,function(){return""+me.apply(this)+z(this.minutes(),2)}),q("hmmss",0,0,function(){return""+me.apply(this)+z(this.minutes(),2)+z(this.seconds(),2)}),q("Hmm",0,0,function(){return""+this.hours()+z(this.minutes(),2)}),q("Hmmss",0,0,function(){return""+this.hours()+z(this.minutes(),2)+z(this.seconds(),2)}),_e("a",!0),_e("A",!1),P("hour","h"),X("a",be),X("A",be),X("H",Sr),X("h",Sr),X("HH",Sr,Ar),X("hh",Sr,Ar),X("hmm",Dr),X("hmmss",Cr),X("Hmm",Dr),X("Hmmss",Cr),tt(["H","HH"],zr),tt(["a","A"],function(t,n,e){e._isPm=e._locale.isPM(t),e._meridiem=t}),tt(["h","hh"],function(t,n,e){n[zr]=_(t),h(e).bigHour=!0}),tt("hmm",function(t,n,e){var r=t.length-2;n[zr]=_(t.substr(0,r)),n[qr]=_(t.substr(r)),h(e).bigHour=!0}),tt("hmmss",function(t,n,e){var r=t.length-4,i=t.length-2;n[zr]=_(t.substr(0,r)),n[qr]=_(t.substr(r,2)),n[Gr]=_(t.substr(i)),h(e).bigHour=!0}),tt("Hmm",function(t,n){var e=t.length-2;n[zr]=_(t.substr(0,e)),n[qr]=_(t.substr(e))}),tt("Hmmss",function(t,n){var e=t.length-4,r=t.length-2;n[zr]=_(t.substr(0,e)),n[qr]=_(t.substr(e,2)),n[Gr]=_(t.substr(r))});var Ei=/[ap]\.?m?\.?/i,Mi=Y("Hours",!0);q("m",["mm",2],0,"minute"),P("minute","m"),X("m",Sr),X("mm",Sr,Ar),tt(["m","mm"],qr);var Si=Y("Minutes",!1);q("s",["ss",2],0,"second"),P("second","s"),X("s",Sr),X("ss",Sr,Ar),tt(["s","ss"],Gr);var Di=Y("Seconds",!1);q("S",0,0,function(){return~~(this.millisecond()/100)}),q(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),q(0,["SSS",3],0,"millisecond"),q(0,["SSSS",4],0,function(){return 10*this.millisecond()}),q(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),q(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),q(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),q(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),q(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),P("millisecond","ms"),X("S",Tr,wr),X("SS",Tr,Ar),X("SSS",Tr,kr);var Ci;for(Ci="SSSS";Ci.length<=9;Ci+="S")X(Ci,Lr);for(Ci="S";Ci.length<=9;Ci+="S")tt(Ci,Ae);var Ti=Y("Milliseconds",!1);q("z",0,0,"zoneAbbr"),q("zz",0,0,"zoneName");var Fi=y.prototype;Fi.add=pi,Fi.calendar=dn,Fi.clone=pn,Fi.diff=xn,Fi.endOf=Ln,Fi.format=En,Fi.from=Mn,Fi.fromNow=Sn,Fi.to=Dn,Fi.toNow=Cn,Fi.get=W,Fi.invalidAt=$n,Fi.isAfter=gn,Fi.isBefore=yn,Fi.isBetween=mn,Fi.isSame=vn,Fi.isSameOrAfter=_n,Fi.isSameOrBefore=bn,Fi.isValid=Yn,Fi.lang=yi,Fi.locale=Tn,Fi.localeData=Fn,Fi.max=ci,Fi.min=si,Fi.parsingFlags=Un,Fi.set=W,Fi.startOf=On,Fi.subtract=gi,Fi.toArray=Pn,Fi.toObject=Rn,Fi.toDate=Nn,Fi.toISOString=kn,Fi.toJSON=jn,Fi.toString=An,Fi.unix=Bn,Fi.valueOf=In,Fi.creationData=Wn,Fi.year=oi,Fi.isLeapYear=xt,Fi.weekYear=qn,Fi.isoWeekYear=Gn,Fi.quarter=Fi.quarters=Kn,Fi.month=ct,Fi.daysInMonth=lt,Fi.week=Fi.weeks=ne,Fi.isoWeek=Fi.isoWeeks=ee,Fi.weeksInYear=Vn,Fi.isoWeeksInYear=Hn,Fi.date=vi,Fi.day=Fi.days=ce,Fi.weekday=le,Fi.isoWeekday=he,Fi.dayOfYear=ye,Fi.hour=Fi.hours=Mi,Fi.minute=Fi.minutes=Si,Fi.second=Fi.seconds=Di,Fi.millisecond=Fi.milliseconds=Ti,Fi.utcOffset=Vt,Fi.utc=Xt,Fi.local=Kt,Fi.parseZone=Qt,Fi.hasAlignedHourOffset=Jt,Fi.isDST=tn,Fi.isDSTShifted=nn,Fi.isLocal=en,Fi.isUtcOffset=rn,Fi.isUtc=an,Fi.isUTC=an,Fi.zoneAbbr=ke,Fi.zoneName=Ee,Fi.dates=w("dates accessor is deprecated. Use date instead.",vi),Fi.months=w("months accessor is deprecated. Use month instead",ct),Fi.years=w("years accessor is deprecated. Use year instead",oi),Fi.zone=w("moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779",Zt);var Oi=Fi,Li={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},Ii={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},Bi="Invalid date",Ni="%d",Pi=/\d{1,2}/,Ri={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ji=D.prototype;ji._calendar=Li,ji.calendar=De,ji._longDateFormat=Ii,ji.longDateFormat=Ce,ji._invalidDate=Bi,ji.invalidDate=Te,ji._ordinal=Ni,ji.ordinal=Fe,ji._ordinalParse=Pi,ji.preparse=Oe,ji.postformat=Oe,ji._relativeTime=Ri,ji.relativeTime=Le,ji.pastFuture=Ie,ji.set=M,ji.months=it,ji._months=Kr,ji.monthsShort=at,ji._monthsShort=Qr,ji.monthsParse=ot,ji._monthsRegex=ti,ji.monthsRegex=ft,ji._monthsShortRegex=Jr,ji.monthsShortRegex=ht,ji.week=Qn,ji._week=mi,ji.firstDayOfYear=te,ji.firstDayOfWeek=Jn,ji.weekdays=ie,ji._weekdays=_i,ji.weekdaysMin=ue,ji._weekdaysMin=xi,ji.weekdaysShort=ae,ji._weekdaysShort=bi,ji.weekdaysParse=se,ji._weekdaysRegex=wi,ji.weekdaysRegex=fe,ji._weekdaysShortRegex=Ai,ji.weekdaysShortRegex=de,ji._weekdaysMinRegex=ki,ji.weekdaysMinRegex=pe,ji.isPM=xe,ji._meridiemParse=Ei,ji.meridiem=we,O("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var n=t%10,e=1===_(t%100/10)?"th":1===n?"st":2===n?"nd":3===n?"rd":"th";return t+e}}),e.lang=w("moment.lang is deprecated. Use moment.locale instead.",O),e.langData=w("moment.langData is deprecated. Use moment.localeData instead.",B);var Yi=Math.abs,Ui=Je("ms"),$i=Je("s"),Wi=Je("m"),zi=Je("h"),qi=Je("d"),Gi=Je("w"),Hi=Je("M"),Vi=Je("y"),Zi=nr("milliseconds"),Xi=nr("seconds"),Ki=nr("minutes"),Qi=nr("hours"),Ji=nr("days"),ta=nr("months"),na=nr("years"),ea=Math.round,ra={s:45,m:45,h:22,d:26,M:11},ia=Math.abs,aa=$t.prototype;aa.abs=We,aa.add=qe,aa.subtract=Ge,aa.as=Ke,aa.asMilliseconds=Ui,aa.asSeconds=$i,aa.asMinutes=Wi,aa.asHours=zi,aa.asDays=qi,aa.asWeeks=Gi,aa.asMonths=Hi,aa.asYears=Vi,aa.valueOf=Qe,aa._bubble=Ve,aa.get=tr,aa.milliseconds=Zi,aa.seconds=Xi,aa.minutes=Ki,aa.hours=Qi,aa.days=Ji,aa.weeks=er,aa.months=ta,aa.years=na,aa.humanize=ur,aa.toISOString=or,aa.toString=or,aa.toJSON=or,aa.locale=Tn,aa.localeData=Fn,aa.toIsoString=w("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",or),aa.lang=yi,q("X",0,0,"unix"),q("x",0,0,"valueOf"),X("x",Ir),X("X",Pr),tt("X",function(t,n,e){e._d=new Date(1e3*parseFloat(t,10))}),tt("x",function(t,n,e){e._d=new Date(_(t))}),e.version="2.13.0",r(Rt),e.fn=Oi,e.min=Yt,e.max=Ut,e.now=li,e.utc=c,e.unix=Me,e.months=Re,e.isDate=a,e.locale=O,e.invalid=d,e.duration=un,e.isMoment=m,e.weekdays=Ye,e.parseZone=Se,e.localeData=B,e.isDuration=Wt,e.monthsShort=je,e.weekdaysMin=$e,e.defineLocale=L,e.updateLocale=I,e.locales=N,e.weekdaysShort=Ue,e.normalizeUnits=R,e.relativeTimeThreshold=ar,e.prototype=Oi;var ua=e;return ua})},{}],105:[function(t,n,e){(function(t){function n(t,n){for(var e=0,r=t.length-1;r>=0;r--){var i=t[r];"."===i?t.splice(r,1):".."===i?(t.splice(r,1),e++):e&&(t.splice(r,1),e--)}if(n)for(;e--;e)t.unshift("..");return t}function r(t,n){if(t.filter)return t.filter(n);for(var e=[],r=0;r=-1&&!i;a--){var u=a>=0?arguments[a]:t.cwd();if("string"!=typeof u)throw new TypeError("Arguments to path.resolve must be strings");u&&(e=u+"/"+e,i="/"===u.charAt(0))}return e=n(r(e.split("/"),function(t){return!!t}),!i).join("/"),(i?"/":"")+e||"."},e.normalize=function(t){var i=e.isAbsolute(t),a="/"===u(t,-1);return t=n(r(t.split("/"),function(t){return!!t}),!i).join("/"),t||i||(t="."),t&&a&&(t+="/"),(i?"/":"")+t},e.isAbsolute=function(t){return"/"===t.charAt(0)},e.join=function(){var t=Array.prototype.slice.call(arguments,0);return e.normalize(r(t,function(t){if("string"!=typeof t)throw new TypeError("Arguments to path.join must be strings");return t}).join("/"))},e.relative=function(t,n){function r(t){for(var n=0;n=0&&""===t[e];e--);return n>e?[]:t.slice(n,e-n+1)}t=e.resolve(t).substr(1),n=e.resolve(n).substr(1);for(var i=r(t.split("/")),a=r(n.split("/")),u=Math.min(i.length,a.length),o=u,s=0;u>s;s++)if(i[s]!==a[s]){o=s;break}for(var c=[],s=o;sn&&(n=t.length+n),t.substr(n,e)}}).call(this,t("_process"))},{_process:106}],106:[function(t,n){function e(){}var r=n.exports={};r.nextTick=function(){var t="undefined"!=typeof window&&window.setImmediate,n="undefined"!=typeof window&&window.MutationObserver,e="undefined"!=typeof window&&window.postMessage&&window.addEventListener;if(t)return function(t){return window.setImmediate(t)};var r=[];if(n){var i=document.createElement("div"),a=new MutationObserver(function(){var t=r.slice();r.length=0,t.forEach(function(t){t()})});return a.observe(i,{attributes:!0}),function(t){r.length||i.setAttribute("yes","no"),r.push(t)}}return e?(window.addEventListener("message",function(t){var n=t.source;if((n===window||null===n)&&"process-tick"===t.data&&(t.stopPropagation(),r.length>0)){var e=r.shift();e()}},!0),function(t){r.push(t),window.postMessage("process-tick","*")}):function(t){setTimeout(t,0)}}(),r.title="browser",r.browser=!0,r.env={},r.argv=[],r.on=e,r.addListener=e,r.once=e,r.off=e,r.removeListener=e,r.removeAllListeners=e,r.emit=e,r.binding=function(){throw new Error("process.binding is not supported")},r.cwd=function(){return"/"},r.chdir=function(){throw new Error("process.chdir is not supported")}},{}],107:[function(t,n){n.exports={name:"mermaid",version:"7.0.0",description:"Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams and gantt charts.",main:"src/mermaid.js",keywords:["diagram","markdown","flowchart","sequence diagram","gantt"],bin:{mermaid:"./bin/mermaid.js"},scripts:{live:"live-server ./test/examples",lint:"node node_modules/eslint/bin/eslint.js src",jison:"gulp jison_legacy",karma:"node node_modules/karma/bin/karma start karma.conf.js --single-run",watch:"source ./scripts/watch.sh",doc:"rm -r build;rm -r dist/www;gulp vartree;cp dist/www/all.html ../mermaid-pages/index.html;cp dist/mermaid.js ../mermaid-pages/javascripts/lib;cp dist/mermaid.forest.css ../mermaid-pages/stylesheets",tape:"node node_modules/tape/bin/tape test/cli_test-*.js",jasmine:"npm run jison &&node node_modules/jasmine-es6/bin/jasmine.js",pretest:"npm run jison",test:"npm run dist && npm run karma && npm run tape","dist-slim-mermaid":"node node_modules/browserify/bin/cmd.js src/mermaid.js -t babelify -s mermaid -o dist/mermaid.slim.js -x d3 && cat dist/mermaid.slim.js | node node_modules/uglifyjs/bin/uglifyjs -mc > dist/mermaid.slim.min.js","dist-slim-mermaidAPI":"node node_modules/browserify/bin/cmd.js src/mermaidAPI.js -t babelify -s mermaidAPI -o dist/mermaidAPI.slim.js -x d3 && cat dist/mermaidAPI.slim.js | node node_modules/uglifyjs/bin/uglifyjs -mc > dist/mermaidAPI.slim.min.js", -"dist-mermaid":"node node_modules/browserify/bin/cmd.js src/mermaid.js -t babelify -s mermaid -o dist/mermaid.js && cat dist/mermaid.js | node node_modules/uglifyjs/bin/uglifyjs -mc > dist/mermaid.min.js","dist-mermaid-nomin":"node node_modules/browserify/bin/cmd.js src/mermaid.js -t babelify -s mermaid -o dist/mermaid.js","dist-mermaidAPI":"node node_modules/browserify/bin/cmd.js src/mermaidAPI.js -t babelify -s mermaidAPI -o dist/mermaidAPI.js && cat dist/mermaidAPI.js | node node_modules/uglifyjs/bin/uglifyjs -mc > dist/mermaidAPI.min.js",dist:"npm run dist-slim-mermaid && npm run dist-slim-mermaidAPI && npm run dist-mermaid && npm run dist-mermaidAPI"},repository:{type:"git",url:"https://github.com/knsv/mermaid"},author:"Knut Sveidqvist",license:"MIT",dependencies:{chalk:"^0.5.1",d3:"3.5.6",dagre:"^0.7.4","dagre-d3":"0.4.10",he:"^0.5.0",lodash:"^4.6.1",minimist:"^1.1.0",mkdirp:"^0.5.0",moment:"^2.9.0",semver:"^4.1.1",which:"^1.0.8"},devDependencies:{async:"^0.9.0","babel-eslint":"^4.1.3",babelify:"^6.4.0",browserify:"~6.2.0",clone:"^0.2.0","codeclimate-test-reporter":"0.0.4",dateformat:"^1.0.11",dox:"^0.8.0",eslint:"^1.6.0","eslint-watch":"^2.1.2","event-stream":"^3.2.0",foundation:"^4.2.1-1","front-matter":"^0.2.0",gulp:"~3.9.0","gulp-bower":"0.0.10","gulp-browserify":"^0.5.0","gulp-bump":"^0.1.11","gulp-concat":"~2.4.1","gulp-data":"^1.1.1","gulp-dox":"^0.1.6","gulp-ext-replace":"^0.2.0","gulp-filelog":"^0.4.1","gulp-front-matter":"^1.2.3","gulp-hogan":"^1.1.0","gulp-if":"^1.2.5","gulp-insert":"^0.4.0","gulp-istanbul":"^0.4.0","gulp-jasmine":"~2.1.0","gulp-jasmine-browser":"^0.2.3","gulp-jison":"~1.2.0","gulp-jshint":"^1.9.0","gulp-less":"^3.0.1","gulp-livereload":"^3.8.0","gulp-marked":"^1.0.0","gulp-mdvars":"^2.0.0","gulp-qunit":"~1.2.1","gulp-rename":"~1.2.0","gulp-shell":"^0.2.10","gulp-tag-version":"^1.2.1","gulp-uglify":"~1.0.1","gulp-util":"^3.0.7","gulp-vartree":"^2.0.1","hogan.js":"^3.0.2",jasmine:"2.3.2","jasmine-es6":"0.0.18",jison:"zaach/jison",jsdom:"^7.0.2","jshint-stylish":"^2.0.1",karma:"^0.13.15","karma-babel-preprocessor":"^6.0.1","karma-browserify":"^4.4.0","karma-jasmine":"^0.3.6","karma-phantomjs-launcher":"^0.2.1","live-server":"^0.9.0","map-stream":"0.0.6",marked:"^0.3.2","mock-browser":"^0.91.34",path:"^0.4.9",phantomjs:"^2.1.3",proxyquire:"^1.7.3","proxyquire-universal":"^1.0.8",proxyquireify:"^3.0.0","require-dir":"^0.3.0",rewire:"^2.1.3",rimraf:"^2.2.8",tape:"^3.0.3",testdom:"^2.0.0",uglifyjs:"^2.4.10","vinyl-source-stream":"^1.1.0",watchify:"^3.6.1"}}},{}],108:[function(t,n){"use strict";var e;if("undefined"!=typeof t)try{e=t("d3")}catch(r){}e||(e=window.d3),n.exports=e,function(){var t=!1;if(t="tspans",e.selection.prototype.textwrap)return!1;if("undefined"==typeof t)var t=!1;e.selection.prototype.textwrap=e.selection.enter.prototype.textwrap=function(n,r){var i,r=parseInt(r)||0,a=this,u=function(t){var n=t[0][0],r=n.tagName.toString();if("rect"!==r)return!1;var i={};return i.x=e.select(n).attr("x")||0,i.y=e.select(n).attr("y")||0,i.width=e.select(n).attr("width")||0,i.height=e.select(n).attr("height")||0,i.attr=t.attr,i},o=function(t){if(t.attr||(t.attr=function(t){return this[t]?this[t]:void 0}),"object"==typeof t&&"undefined"!=typeof t.x&&"undefined"!=typeof t.y&&"undefined"!=typeof t.width&&"undefined"!=typeof t.height)return t;if("function"==typeof Array.isArray&&Array.isArray(t)||"[object Array]"===Object.prototype.toString.call(t)){var n=u(t);return n}return!1},s=function(t,n){var e=t;return 0!==n&&(e.x=parseInt(e.x)+n,e.y=parseInt(e.y)+n,e.width-=2*n,e.height-=2*n),e},c=o(n);if(r&&(c=s(c,r)),0!=a.length&&e&&n&&c){n=c;var l,h=function(t){var r=e.select(t[0].parentNode),a=r.select("text"),u=a.style("line-height"),o=a.text();a.remove();var s=r.append("foreignObject");s.attr("requiredFeatures","http://www.w3.org/TR/SVG11/feature#Extensibility").attr("x",n.x).attr("y",n.y).attr("width",n.width).attr("height",n.height);var c=s.append("xhtml:div").attr("class","wrapped");c.style("height",n.height).style("width",n.width).html(o),u&&c.style("line-height",u),i=r.select("foreignObject")},f=function(t){var a,u=t[0],o=u.parentNode,s=e.select(u),c=u.getBBox().height,l=u.getBBox().width,h=c,f=s.style("line-height");if(a=f&&parseInt(f)?parseInt(f.replace("px","")):h,l>n.width){var d=s.text();if(s.text(""),d){var p,g;if(-1!==d.indexOf(" ")){var p=" ";g=d.split(" ")}else{p="";var y=d.length,m=Math.ceil(l/n.width),v=Math.floor(y/m);v*m>=y||m++;for(var _,b,g=[],x=0;m>x;x++)b=x*v,_=d.substr(b,v),g.push(_)}for(var w=[],A=0,k={},x=0;xn.width&&S&&""!==S&&(A+=D,k={string:S,width:D,offset:A},w.push(k),s.text(""),s.text(M),x==g.length-1&&(E=M,s.text(E),C=u.getComputedTextLength())),x==g.length-1){s.text("");var T=E;T&&""!==T&&(C-A>0&&(C-=A),k={string:T,width:C,offset:A},w.push(k))}}var F;s.text("");for(var x=0;x0){w[x-1]}x*a0?a:void 0}),F.attr("x",function(){var t=n.x;return r&&(t+=r),t}))}}}s.attr("y",function(){var t=n.y;return a&&(t+=a),r&&(t+=r),t}),s.attr("x",function(){var t=n.x;return r&&(t+=r),t}),i=e.select(o).selectAll("text")};t&&("foreignobjects"==t?l=h:"tspans"==t&&(l=f)),t||(l="undefined"!=typeof SVGForeignObjectElement?h:f);for(var d=0;d "+t.w+": "+JSON.stringify(u.edge(t))),p(i,u.edge(t),u.edge(t).relation)}),i.attr("height","100%"),i.attr("width","100%")}},{"../../d3":108,"../../logger":130,"./classDb":109,"./parser/classDiagram":111,dagre:52}],111:[function(t,n,e){(function(r){"use strict";var i=function(){function t(){this.yy={}}var n=function(t,n,e,r){for(e=e||{},r=t.length;r--;e[t[r]]=n);return e},e=[1,11],r=[1,12],i=[1,13],a=[1,15],u=[1,16],o=[1,17],s=[6,8],c=[1,26],l=[1,27],h=[1,28],f=[1,29],d=[1,30],p=[1,31],g=[6,8,13,17,23,26,27,28,29,30,31],y=[6,8,13,17,23,26,27,28,29,30,31,45,46,47],m=[23,45,46,47],v=[23,30,31,45,46,47],_=[23,26,27,28,29,45,46,47],b=[6,8,13],x=[1,46],w={trace:function(){},yy:{},symbols_:{error:2,mermaidDoc:3,graphConfig:4,CLASS_DIAGRAM:5,NEWLINE:6,statements:7,EOF:8,statement:9,className:10,alphaNumToken:11,relationStatement:12,LABEL:13,classStatement:14,methodStatement:15,CLASS:16,STRUCT_START:17,members:18,STRUCT_STOP:19,MEMBER:20,SEPARATOR:21,relation:22,STR:23,relationType:24,lineType:25,AGGREGATION:26,EXTENSION:27,COMPOSITION:28,DEPENDENCY:29,LINE:30,DOTTED_LINE:31,commentToken:32,textToken:33,graphCodeTokens:34,textNoTagsToken:35,TAGSTART:36,TAGEND:37,"==":38,"--":39,PCT:40,DEFAULT:41,SPACE:42,MINUS:43,keywords:44,UNICODE_TEXT:45,NUM:46,ALPHA:47,$accept:0,$end:1},terminals_:{2:"error",5:"CLASS_DIAGRAM",6:"NEWLINE",8:"EOF",13:"LABEL",16:"CLASS",17:"STRUCT_START",19:"STRUCT_STOP",20:"MEMBER",21:"SEPARATOR",23:"STR",26:"AGGREGATION",27:"EXTENSION",28:"COMPOSITION",29:"DEPENDENCY",30:"LINE",31:"DOTTED_LINE",34:"graphCodeTokens",36:"TAGSTART",37:"TAGEND",38:"==",39:"--",40:"PCT",41:"DEFAULT",42:"SPACE",43:"MINUS",44:"keywords",45:"UNICODE_TEXT",46:"NUM",47:"ALPHA"},productions_:[0,[3,1],[4,4],[7,1],[7,3],[10,2],[10,1],[9,1],[9,2],[9,1],[9,1],[14,2],[14,5],[18,1],[18,2],[15,1],[15,2],[15,1],[15,1],[12,3],[12,4],[12,4],[12,5],[22,3],[22,2],[22,2],[22,1],[24,1],[24,1],[24,1],[24,1],[25,1],[25,1],[32,1],[32,1],[33,1],[33,1],[33,1],[33,1],[33,1],[33,1],[33,1],[35,1],[35,1],[35,1],[35,1],[11,1],[11,1],[11,1]],performAction:function(t,n,e,r,i,a){var u=a.length-1;switch(i){case 5:this.$=a[u-1]+a[u];break;case 6:this.$=a[u];break;case 7:r.addRelation(a[u]);break;case 8:a[u-1].title=r.cleanupLabel(a[u]),r.addRelation(a[u-1]);break;case 12:r.addMembers(a[u-3],a[u-1]);break;case 13:this.$=[a[u]];break;case 14:a[u].push(a[u-1]),this.$=a[u];break;case 15:break;case 16:r.addMembers(a[u-1],r.cleanupLabel(a[u]));break;case 17:console.warn("Member",a[u]);break;case 18:break;case 19:this.$={id1:a[u-2],id2:a[u],relation:a[u-1],relationTitle1:"none",relationTitle2:"none"};break;case 20:this.$={id1:a[u-3],id2:a[u],relation:a[u-1],relationTitle1:a[u-2],relationTitle2:"none"};break;case 21:this.$={id1:a[u-3],id2:a[u],relation:a[u-2],relationTitle1:"none",relationTitle2:a[u-1]};break;case 22:this.$={id1:a[u-4],id2:a[u],relation:a[u-2],relationTitle1:a[u-3],relationTitle2:a[u-1]};break;case 23:this.$={type1:a[u-2],type2:a[u],lineType:a[u-1]};break;case 24:this.$={type1:"none",type2:a[u],lineType:a[u-1]};break;case 25:this.$={type1:a[u-1],type2:"none",lineType:a[u]};break;case 26:this.$={type1:"none",type2:"none",lineType:a[u]};break;case 27:this.$=r.relationType.AGGREGATION;break;case 28:this.$=r.relationType.EXTENSION;break;case 29:this.$=r.relationType.COMPOSITION;break;case 30:this.$=r.relationType.DEPENDENCY;break;case 31:this.$=r.lineType.LINE;break;case 32:this.$=r.lineType.DOTTED_LINE}},table:[{3:1,4:2,5:[1,3]},{1:[3]},{1:[2,1]},{6:[1,4]},{7:5,9:6,10:10,11:14,12:7,14:8,15:9,16:e,20:r,21:i,45:a,46:u,47:o},{8:[1,18]},{6:[1,19],8:[2,3]},n(s,[2,7],{13:[1,20]}),n(s,[2,9]),n(s,[2,10]),n(s,[2,15],{22:21,24:24,25:25,13:[1,23],23:[1,22],26:c,27:l,28:h,29:f,30:d,31:p}),{10:32,11:14,45:a,46:u,47:o},n(s,[2,17]),n(s,[2,18]),n(g,[2,6],{11:14,10:33,45:a,46:u,47:o}),n(y,[2,46]),n(y,[2,47]),n(y,[2,48]),{1:[2,2]},{7:34,9:6,10:10,11:14,12:7,14:8,15:9,16:e,20:r,21:i,45:a,46:u,47:o},n(s,[2,8]),{10:35,11:14,23:[1,36],45:a,46:u,47:o},{22:37,24:24,25:25,26:c,27:l,28:h,29:f,30:d,31:p},n(s,[2,16]),{25:38,30:d,31:p},n(m,[2,26],{24:39,26:c,27:l,28:h,29:f}),n(v,[2,27]),n(v,[2,28]),n(v,[2,29]),n(v,[2,30]),n(_,[2,31]),n(_,[2,32]),n(s,[2,11],{17:[1,40]}),n(g,[2,5]),{8:[2,4]},n(b,[2,19]),{10:41,11:14,45:a,46:u,47:o},{10:42,11:14,23:[1,43],45:a,46:u,47:o},n(m,[2,25],{24:44,26:c,27:l,28:h,29:f}),n(m,[2,24]),{18:45,20:x},n(b,[2,21]),n(b,[2,20]),{10:47,11:14,45:a,46:u,47:o},n(m,[2,23]),{19:[1,48]},{18:49,19:[2,13],20:x},n(b,[2,22]),n(s,[2,12]),{19:[2,14]}],defaultActions:{2:[2,1],18:[2,2],34:[2,4],49:[2,14]},parseError:function(t,n){if(!n.recoverable){var e=function(t,n){this.message=t,this.hash=n};throw e.prototype=Error,new e(t,n)}this.trace(t)},parse:function(t){var n=this,e=[0],r=[null],i=[],a=this.table,u="",o=0,s=0,c=0,l=2,h=1,f=i.slice.call(arguments,1),d=Object.create(this.lexer),p={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(p.yy[g]=this.yy[g]);d.setInput(t,p.yy),p.yy.lexer=d,p.yy.parser=this,"undefined"==typeof d.yylloc&&(d.yylloc={});var y=d.yylloc;i.push(y);var m=d.options&&d.options.ranges;this.parseError="function"==typeof p.yy.parseError?p.yy.parseError:Object.getPrototypeOf(this).parseError;for(var v,_,b,x,w,A,k,E,M,S=function(){var t;return t=d.lex()||h,"number"!=typeof t&&(t=n.symbols_[t]||t),t},D={};;){if(b=e[e.length-1],this.defaultActions[b]?x=this.defaultActions[b]:((null===v||"undefined"==typeof v)&&(v=S()),x=a[b]&&a[b][v]),"undefined"==typeof x||!x.length||!x[0]){var C="";M=[];for(A in a[b])this.terminals_[A]&&A>l&&M.push("'"+this.terminals_[A]+"'");C=d.showPosition?"Parse error on line "+(o+1)+":\n"+d.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[v]||v)+"'":"Parse error on line "+(o+1)+": Unexpected "+(v==h?"end of input":"'"+(this.terminals_[v]||v)+"'"),this.parseError(C,{text:d.match,token:this.terminals_[v]||v,line:d.yylineno,loc:y,expected:M})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+v);switch(x[0]){case 1:e.push(v),r.push(d.yytext),i.push(d.yylloc),e.push(x[1]),v=null,_?(v=_,_=null):(s=d.yyleng,u=d.yytext,o=d.yylineno,y=d.yylloc,c>0&&c--);break;case 2:if(k=this.productions_[x[1]][1],D.$=r[r.length-k],D._$={first_line:i[i.length-(k||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(k||1)].first_column,last_column:i[i.length-1].last_column},m&&(D._$.range=[i[i.length-(k||1)].range[0],i[i.length-1].range[1]]),w=this.performAction.apply(D,[u,s,o,p.yy,x[1],r,i].concat(f)),"undefined"!=typeof w)return w;k&&(e=e.slice(0,-1*k*2),r=r.slice(0,-1*k),i=i.slice(0,-1*k)),e.push(this.productions_[x[1]][0]),r.push(D.$),i.push(D._$),E=a[e[e.length-2]][e[e.length-1]],e.push(E);break;case 3:return!0}}return!0}},A=function(){var t={EOF:1,parseError:function(t,n){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,n)},setInput:function(t,n){return this.yy=n||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t;var n=t.match(/(?:\r\n?|\n).*/g);return n?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var n=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===r.length?this.yylloc.first_column:0)+r[r.length-e.length].length-e[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),n=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+n+"^"},test_match:function(t,n){var e,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),r=t[0].match(/(?:\r\n?|\n).*/g),r&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,n,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var t,n,e,r;this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;an[0].length)){if(n=e,r=a,this.options.backtrack_lexer){if(t=this.test_match(e,i[a]),t!==!1)return t;if(this._backtrack){n=!1;continue}return!1}if(!this.options.flex)break}return n?(t=this.test_match(n,i[r]),t!==!1?t:!1):""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t?t:this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){var t=this.conditionStack.length-1;return t>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return t=this.conditionStack.length-1-Math.abs(t||0),t>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,n,e,r){switch(e){case 0:break;case 1:return 6;case 2:break;case 3:return 5;case 4:return this.begin("struct"),17;case 5:return this.popState(),19;case 6:break;case 7:return"MEMBER";case 8:return 16;case 9:this.begin("string");break;case 10:this.popState();break;case 11:return"STR";case 12:return 27;case 13:return 27;case 14:return 29;case 15:return 29;case 16:return 28;case 17:return 26;case 18:return 30;case 19:return 31;case 20:return 13;case 21:return 43;case 22:return"DOT";case 23:return"PLUS";case 24:return 40;case 25:return"EQUALS";case 26:return"EQUALS";case 27:return 47;case 28:return"PUNCTUATION";case 29:return 46;case 30:return 45;case 31:return 42;case 32:return 8}},rules:[/^(?:%%[^\n]*)/,/^(?:\n+)/,/^(?:\s+)/,/^(?:classDiagram\b)/,/^(?:[\{])/,/^(?:\})/,/^(?:[\n])/,/^(?:[^\{\}\n]*)/,/^(?:class\b)/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:\s*<\|)/,/^(?:\s*\|>)/,/^(?:\s*>)/,/^(?:\s*<)/,/^(?:\s*\*)/,/^(?:\s*o\b)/,/^(?:--)/,/^(?:\.\.)/,/^(?::[^#\n;]+)/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:[A-Za-z]+)/,/^(?:[!"#$%&'*+,-.`?\\_\/])/,/^(?:[0-9]+)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\s)/,/^(?:$)/],conditions:{string:{rules:[10,11],inclusive:!1},struct:{rules:[5,6,7],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,8,9,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],inclusive:!0}}};return t}();return w.lexer=A,t.prototype=w,w.Parser=t,new t}();"undefined"!=typeof t&&"undefined"!=typeof e&&(e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(n){n[1]||(console.log("Usage: "+n[0]+" FILE"),r.exit(1));var i=t("fs").readFileSync(t("path").normalize(n[1]),"utf8");return e.parser.parse(i)},"undefined"!=typeof n&&t.main===n&&e.main(r.argv.slice(1)))}).call(this,t("_process"))},{_process:106,fs:1,path:105}],112:[function(t,n,e){(function(n){"use strict";var r=t("../../logger"),i=new r.Log,a="",u=!1;e.setMessage=function(t){i.debug("Setting message to: "+t),a=t},e.getMessage=function(){return a},e.setInfo=function(t){u=t},e.getInfo=function(){return u},e.parseError=function(t,e){n.mermaidAPI.parseError(t,e)}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../../logger":130}],113:[function(t,n,e){"use strict";var r=t("./exampleDb"),i=t("./parser/example.js"),a=t("../../d3"),u=t("../../logger"),o=new u.Log;e.draw=function(t,n,e){var u;u=i.parser,u.yy=r,o.debug("Renering example diagram"),u.parse(t);var s=a.select("#"+n),c=s.append("g");c.append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size","32px").style("text-anchor","middle").text("mermaid "+e),s.attr("height",100),s.attr("width",400)}},{"../../d3":108,"../../logger":130,"./exampleDb":112,"./parser/example.js":114}],114:[function(t,n,e){(function(r){"use strict";var i=function(){function t(){this.yy={}}var n=function(t,n,e,r){for(e=e||{},r=t.length;r--;e[t[r]]=n);return e},e=[6,9,10,12],r={trace:function(){},yy:{},symbols_:{error:2,start:3,info:4,document:5,EOF:6,line:7,statement:8,NL:9,showInfo:10,message:11,say:12,TXT:13,$accept:0,$end:1},terminals_:{2:"error",4:"info",6:"EOF",9:"NL",10:"showInfo",12:"say",13:"TXT"},productions_:[0,[3,3],[5,0],[5,2],[7,1],[7,1],[8,1],[8,1],[11,2]],performAction:function(t,n,e,r,i,a){var u=a.length-1;switch(i){case 1:return r;case 4:break;case 6:r.setInfo(!0);break;case 7:r.setMessage(a[u]);break;case 8:this.$=a[u-1].substring(1).trim().replace(/\\n/gm,"\n")}},table:[{3:1,4:[1,2]},{1:[3]},n(e,[2,2],{5:3}),{6:[1,4],7:5,8:6,9:[1,7],10:[1,8],11:9,12:[1,10]},{1:[2,1]},n(e,[2,3]),n(e,[2,4]),n(e,[2,5]),n(e,[2,6]),n(e,[2,7]),{13:[1,11]},n(e,[2,8])],defaultActions:{4:[2,1]},parseError:function(t,n){if(!n.recoverable){var e=function(t,n){this.message=t,this.hash=n};throw e.prototype=Error,new e(t,n)}this.trace(t)},parse:function(t){var n=this,e=[0],r=[null],i=[],a=this.table,u="",o=0,s=0,c=0,l=2,h=1,f=i.slice.call(arguments,1),d=Object.create(this.lexer),p={ -yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(p.yy[g]=this.yy[g]);d.setInput(t,p.yy),p.yy.lexer=d,p.yy.parser=this,"undefined"==typeof d.yylloc&&(d.yylloc={});var y=d.yylloc;i.push(y);var m=d.options&&d.options.ranges;this.parseError="function"==typeof p.yy.parseError?p.yy.parseError:Object.getPrototypeOf(this).parseError;for(var v,_,b,x,w,A,k,E,M,S=function(){var t;return t=d.lex()||h,"number"!=typeof t&&(t=n.symbols_[t]||t),t},D={};;){if(b=e[e.length-1],this.defaultActions[b]?x=this.defaultActions[b]:((null===v||"undefined"==typeof v)&&(v=S()),x=a[b]&&a[b][v]),"undefined"==typeof x||!x.length||!x[0]){var C="";M=[];for(A in a[b])this.terminals_[A]&&A>l&&M.push("'"+this.terminals_[A]+"'");C=d.showPosition?"Parse error on line "+(o+1)+":\n"+d.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[v]||v)+"'":"Parse error on line "+(o+1)+": Unexpected "+(v==h?"end of input":"'"+(this.terminals_[v]||v)+"'"),this.parseError(C,{text:d.match,token:this.terminals_[v]||v,line:d.yylineno,loc:y,expected:M})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+v);switch(x[0]){case 1:e.push(v),r.push(d.yytext),i.push(d.yylloc),e.push(x[1]),v=null,_?(v=_,_=null):(s=d.yyleng,u=d.yytext,o=d.yylineno,y=d.yylloc,c>0&&c--);break;case 2:if(k=this.productions_[x[1]][1],D.$=r[r.length-k],D._$={first_line:i[i.length-(k||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(k||1)].first_column,last_column:i[i.length-1].last_column},m&&(D._$.range=[i[i.length-(k||1)].range[0],i[i.length-1].range[1]]),w=this.performAction.apply(D,[u,s,o,p.yy,x[1],r,i].concat(f)),"undefined"!=typeof w)return w;k&&(e=e.slice(0,-1*k*2),r=r.slice(0,-1*k),i=i.slice(0,-1*k)),e.push(this.productions_[x[1]][0]),r.push(D.$),i.push(D._$),E=a[e[e.length-2]][e[e.length-1]],e.push(E);break;case 3:return!0}}return!0}},i=function(){var t={EOF:1,parseError:function(t,n){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,n)},setInput:function(t,n){return this.yy=n||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t;var n=t.match(/(?:\r\n?|\n).*/g);return n?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var n=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===r.length?this.yylloc.first_column:0)+r[r.length-e.length].length-e[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),n=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+n+"^"},test_match:function(t,n){var e,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),r=t[0].match(/(?:\r\n?|\n).*/g),r&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,n,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var t,n,e,r;this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;an[0].length)){if(n=e,r=a,this.options.backtrack_lexer){if(t=this.test_match(e,i[a]),t!==!1)return t;if(this._backtrack){n=!1;continue}return!1}if(!this.options.flex)break}return n?(t=this.test_match(n,i[r]),t!==!1?t:!1):""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t?t:this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){var t=this.conditionStack.length-1;return t>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return t=this.conditionStack.length-1-Math.abs(t||0),t>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,n,e,r){switch(e){case 0:return 9;case 1:return 10;case 2:return 4;case 3:return 12;case 4:return 13;case 5:return 6;case 6:return"INVALID"}},rules:[/^(?:[\n]+)/i,/^(?:showInfo\b)/i,/^(?:info\b)/i,/^(?:say\b)/i,/^(?::[^#\n;]+)/i,/^(?:$)/i,/^(?:.)/i],conditions:{INITIAL:{rules:[0,1,2,3,4,5,6],inclusive:!0}}};return t}();return r.lexer=i,t.prototype=r,r.Parser=t,new t}();"undefined"!=typeof t&&"undefined"!=typeof e&&(e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(n){n[1]||(console.log("Usage: "+n[0]+" FILE"),r.exit(1));var i=t("fs").readFileSync(t("path").normalize(n[1]),"utf8");return e.parser.parse(i)},"undefined"!=typeof n&&t.main===n&&e.main(r.argv.slice(1)))}).call(this,t("_process"))},{_process:106,fs:1,path:105}],115:[function(t,n){"use strict";var e,r=t("../../logger"),i=new r.Log;if(t)try{e=t("dagre-d3")}catch(a){i.debug("Could not load dagre-d3")}e||(e=window.dagreD3),n.exports=e},{"../../logger":130,"dagre-d3":3}],116:[function(t,n,e){"use strict";var r=t("./graphDb"),i=t("./parser/flow"),a=t("./parser/dot"),u=t("../../d3"),o=t("./dagre-d3"),s=t("../../logger"),c=new s.Log,l={};n.exports.setConf=function(t){var n,e=Object.keys(t);for(n=0;n0&&(u=a.classes.join(" "));var o="";o=r(o,a.styles),i="undefined"==typeof a.text?a.id:a.text;var s="";if(l.htmlLabels)s="html",i=i.replace(/fa:fa[\w\-]+/g,function(t){return''});else{var c=document.createElementNS("http://www.w3.org/2000/svg","text"),h=i.split(/
    /),f=0;for(f=0;f"):(a.labelType="text",a.style="stroke: #333; stroke-width: 1.5px;fill:none",a.label=i.text.replace(/
    /g,"\n"))):a.label=i.text.replace(/
    /g,"\n")),n.setEdge(i.start,i.end,a,r)})},e.getClasses=function(t,n){var e;r.clear(),e=n?a.parser:i.parser,e.yy=r,e.parse(t);var u=r.getClasses();return"undefined"==typeof u["default"]&&(u["default"]={id:"default"},u["default"].styles=[],u["default"].clusterStyles=["rx:4px","fill: rgb(255, 255, 222)","rx: 4px","stroke: rgb(170, 170, 51)","stroke-width: 1px"],u["default"].nodeLabelStyles=["fill:#000","stroke:none","font-weight:300",'font-family:"Helvetica Neue",Helvetica,Arial,sans-serf',"font-size:14px"],u["default"].edgeLabelStyles=["fill:#000","stroke:none","font-weight:300",'font-family:"Helvetica Neue",Helvetica,Arial,sans-serf',"font-size:14px"]),u},e.draw=function(t,n,s){c.debug("Drawing flowchart");var h;r.clear(),h=s?a.parser:i.parser,h.yy=r;try{h.parse(t)}catch(f){c.debug("Parsing failed")}var d;d=r.getDirection(),"undefined"==typeof d&&(d="TD");var p,g=new o.graphlib.Graph({multigraph:!0,compound:!0}).setGraph({rankdir:d,marginx:20,marginy:20}).setDefaultEdgeLabel(function(){return{}}),y=r.getSubGraphs(),m=0;for(m=y.length-1;m>=0;m--)p=y[m],r.addVertex(p.id,p.title,"group",void 0);var v=r.getVertices(),_=r.getEdges();m=0;var b;for(m=y.length-1;m>=0;m--)for(p=y[m],u.selectAll("cluster").append("text"),b=0;b0?t.split(",").forEach(function(t){"undefined"!=typeof vertices[t]&&vertices[t].classes.push(n)}):"undefined"!=typeof vertices[t]&&vertices[t].classes.push(n)};var setTooltip=function(t,n){"undefined"!=typeof n&&(tooltips[t]=n)},setClickFun=function setClickFun(id,functionName){"undefined"!=typeof functionName&&"undefined"!=typeof vertices[id]&&funs.push(function(element){var elem=d3.select(element).select("#"+id);null!==elem&&elem.on("click",function(){eval(functionName+"('"+id+"')")})})},setLink=function(t,n){"undefined"!=typeof n&&"undefined"!=typeof vertices[t]&&funs.push(function(e){var r=d3.select(e).select("#"+t);null!==r&&r.on("click",function(){window.open(n,"newTab")})})};exports.getTooltip=function(t){return tooltips[t]},exports.setClickEvent=function(t,n,e,r){t.indexOf(",")>0?t.split(",").forEach(function(t){setTooltip(t,r),setClickFun(t,n),setLink(t,e)}):(setTooltip(t,r),setClickFun(t,n),setLink(t,e))},exports.bindFunctions=function(t){funs.forEach(function(n){n(t)})},exports.getDirection=function(){return direction},exports.getVertices=function(){return vertices},exports.getEdges=function(){return edges},exports.getClasses=function(){return classes};var setupToolTips=function(t){var n=d3.select(".mermaidTooltip");null===n[0][0]&&(n=d3.select("body").append("div").attr("class","mermaidTooltip").style("opacity",0));var e=d3.select(t).select("svg"),r=e.selectAll("g.node");r.on("mouseover",function(){var t=d3.select(this),e=t.attr("title");if(null!==e){var r=this.getBoundingClientRect();n.transition().duration(200).style("opacity",".9"),n.html(t.attr("title")).style("left",r.left+(r.right-r.left)/2+"px").style("top",r.top-14+document.body.scrollTop+"px"),t.classed("hover",!0)}}).on("mouseout",function(){n.transition().duration(500).style("opacity",0);var t=d3.select(this);t.classed("hover",!1)})};funs.push(setupToolTips),exports.clear=function(){vertices={},classes={},edges=[],funs=[],funs.push(setupToolTips),subGraphs=[],subCount=0,tooltips=[]},exports.defaultStyle=function(){return"fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"},exports.addSubGraph=function(t,n){function e(t){var n={"boolean":{},number:{},string:{}},e=[];return t.filter(function(t){var r=typeof t;return" "===t?!1:r in n?n[r].hasOwnProperty(t)?!1:n[r][t]=!0:e.indexOf(t)>=0?!1:e.push(t)})}var r=[];r=e(r.concat.apply(r,t));var i={id:"subGraph"+subCount,nodes:r,title:n};return subGraphs.push(i),subCount+=1,i.id};var getPosForId=function(t){var n;for(n=0;n2e3)){if(posCrossRef[secCount]=e,subGraphs[e].id===n)return{result:!0,count:0};for(var i=0,a=1;i=0){var o=t(n,u);if(o.result)return{result:!0,count:a+o.count};a+=o.count}i+=1}return{result:!1,count:a}}};exports.getDepthFirstPos=function(t){return posCrossRef[t]},exports.indexNodes=function(){secCount=-1,subGraphs.length>0&&indexNodes("none",subGraphs.length-1,0)},exports.getSubGraphs=function(){return subGraphs},exports.parseError=function(t,n){global.mermaidAPI.parseError(t,n)}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../../d3":108,"../../logger":130,"../../utils":132}],118:[function(t,n,e){(function(r){"use strict";var i=function(){function t(){this.yy={}}var n=function(t,n,e,r){for(e=e||{},r=t.length;r--;e[t[r]]=n);return e},e=[1,5],r=[1,6],i=[1,12],a=[1,13],u=[1,14],o=[1,15],s=[1,16],c=[1,17],l=[1,18],h=[1,19],f=[1,20],d=[1,21],p=[1,22],g=[8,16,17,18,19,20,21,22,23,24,25,26],y=[1,37],m=[1,33],v=[1,34],_=[1,35],b=[1,36],x=[8,10,16,17,18,19,20,21,22,23,24,25,26,28,32,37,39,40,45,57,58],w=[10,28],A=[10,28,37,57,58],k=[2,49],E=[1,45],M=[1,48],S=[1,49],D=[1,52],C=[2,65],T=[1,65],F=[1,66],O=[1,67],L=[1,68],I=[1,69],B=[1,70],N=[1,71],P=[1,72],R=[1,73],j=[8,16,17,18,19,20,21,22,23,24,25,26,47],Y=[10,28,37],U={trace:function(){},yy:{},symbols_:{error:2,expressions:3,graph:4,EOF:5,graphStatement:6,idStatement:7,"{":8,stmt_list:9,"}":10,strict:11,GRAPH:12,DIGRAPH:13,textNoTags:14,textNoTagsToken:15,ALPHA:16,NUM:17,COLON:18,PLUS:19,EQUALS:20,MULT:21,DOT:22,BRKT:23,SPACE:24,MINUS:25,keywords:26,stmt:27,";":28,node_stmt:29,edge_stmt:30,attr_stmt:31,"=":32,subgraph:33,attr_list:34,NODE:35,EDGE:36,"[":37,a_list:38,"]":39,",":40,edgeRHS:41,node_id:42,edgeop:43,port:44,":":45,compass_pt:46,SUBGRAPH:47,n:48,ne:49,e:50,se:51,s:52,sw:53,w:54,nw:55,c:56,ARROW_POINT:57,ARROW_OPEN:58,$accept:0,$end:1},terminals_:{2:"error",5:"EOF",8:"{",10:"}",11:"strict",12:"GRAPH",13:"DIGRAPH",16:"ALPHA",17:"NUM",18:"COLON",19:"PLUS",20:"EQUALS",21:"MULT",22:"DOT",23:"BRKT",24:"SPACE",25:"MINUS",26:"keywords",28:";",32:"=",35:"NODE",36:"EDGE",37:"[",39:"]",40:",",45:":",47:"SUBGRAPH",48:"n",49:"ne",50:"e",51:"se",52:"s",53:"sw",54:"w",55:"nw",56:"c",57:"ARROW_POINT",58:"ARROW_OPEN"},productions_:[0,[3,2],[4,5],[4,6],[4,4],[6,1],[6,1],[7,1],[14,1],[14,2],[15,1],[15,1],[15,1],[15,1],[15,1],[15,1],[15,1],[15,1],[15,1],[15,1],[15,1],[9,1],[9,3],[27,1],[27,1],[27,1],[27,3],[27,1],[31,2],[31,2],[31,2],[34,4],[34,3],[34,3],[34,2],[38,5],[38,5],[38,3],[30,3],[30,3],[30,2],[30,2],[41,3],[41,3],[41,2],[41,2],[29,2],[29,1],[42,2],[42,1],[44,4],[44,2],[44,2],[33,5],[33,4],[33,3],[46,1],[46,1],[46,1],[46,1],[46,1],[46,1],[46,1],[46,1],[46,1],[46,0],[43,1],[43,1]],performAction:function(t,n,e,r,i,a){var u=a.length-1;switch(i){case 1:this.$=a[u-1];break;case 2:this.$=a[u-4];break;case 3:this.$=a[u-5];break;case 4:this.$=a[u-3];break;case 8:case 10:case 11:this.$=a[u];break;case 9:this.$=a[u-1]+""+a[u];break;case 12:case 13:case 14:case 15:case 16:case 18:case 19:case 20:this.$=a[u];break;case 17:this.$="
    ";break;case 39:this.$="oy";break;case 40:r.addLink(a[u-1],a[u].id,a[u].op),this.$="oy";break;case 42:r.addLink(a[u-1],a[u].id,a[u].op),this.$={op:a[u-2],id:a[u-1]};break;case 44:this.$={op:a[u-1],id:a[u]};break;case 48:r.addVertex(a[u-1]),this.$=a[u-1];break;case 49:r.addVertex(a[u]),this.$=a[u];break;case 66:this.$="arrow";break;case 67:this.$="arrow_open"}},table:[{3:1,4:2,6:3,11:[1,4],12:e,13:r},{1:[3]},{5:[1,7]},{7:8,8:[1,9],14:10,15:11,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p},{6:23,12:e,13:r},n(g,[2,5]),n(g,[2,6]),{1:[2,1]},{8:[1,24]},{7:30,8:y,9:25,12:m,14:10,15:11,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p,27:26,29:27,30:28,31:29,33:31,35:v,36:_,42:32,47:b},n([8,10,28,32,37,39,40,45,57,58],[2,7],{15:38,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p}),n(x,[2,8]),n(x,[2,10]),n(x,[2,11]),n(x,[2,12]),n(x,[2,13]),n(x,[2,14]),n(x,[2,15]),n(x,[2,16]),n(x,[2,17]),n(x,[2,18]),n(x,[2,19]),n(x,[2,20]),{7:39,14:10,15:11,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p},{7:30,8:y,9:40,12:m,14:10,15:11,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p,27:26,29:27,30:28,31:29,33:31,35:v,36:_,42:32,47:b},{10:[1,41]},{10:[2,21],28:[1,42]},n(w,[2,23]),n(w,[2,24]),n(w,[2,25]),n(A,k,{44:44,32:[1,43],45:E}),n(w,[2,27],{41:46,43:47,57:M,58:S}),n(w,[2,47],{43:47,34:50,41:51,37:D,57:M,58:S}),{34:53,37:D},{34:54,37:D},{34:55,37:D},{7:56,8:[1,57],14:10,15:11,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p},{7:30,8:y,9:58,12:m,14:10,15:11,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p,27:26,29:27,30:28,31:29,33:31,35:v,36:_,42:32,47:b},n(x,[2,9]),{8:[1,59]},{10:[1,60]},{5:[2,4]},{7:30,8:y,9:61,12:m,14:10,15:11,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p,27:26,29:27,30:28,31:29,33:31,35:v,36:_,42:32,47:b},{7:62,14:10,15:11,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p},n(A,[2,48]),n(A,C,{14:10,15:11,7:63,46:64,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p,48:T,49:F,50:O,51:L,52:I,53:B,54:N,55:P,56:R}),n(w,[2,41],{34:74,37:D}),{7:77,8:y,14:10,15:11,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p,33:76,42:75,47:b},n(j,[2,66]),n(j,[2,67]),n(w,[2,46]),n(w,[2,40],{34:78,37:D}),{7:81,14:10,15:11,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p,38:79,39:[1,80]},n(w,[2,28]),n(w,[2,29]),n(w,[2,30]),{8:[1,82]},{7:30,8:y,9:83,12:m,14:10,15:11,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p,27:26,29:27,30:28,31:29,33:31,35:v,36:_,42:32,47:b},{10:[1,84]},{7:30,8:y,9:85,12:m,14:10,15:11,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p,27:26,29:27,30:28,31:29,33:31,35:v,36:_,42:32,47:b},{5:[2,2]},{10:[2,22]},n(w,[2,26]),n(A,[2,51],{45:[1,86]}),n(A,[2,52]),n(A,[2,56]),n(A,[2,57]),n(A,[2,58]),n(A,[2,59]),n(A,[2,60]),n(A,[2,61]),n(A,[2,62]),n(A,[2,63]),n(A,[2,64]),n(w,[2,38]),n(Y,[2,44],{43:47,41:87,57:M,58:S}),n(Y,[2,45],{43:47,41:88,57:M,58:S}),n(A,k,{44:44,45:E}),n(w,[2,39]),{39:[1,89]},n(w,[2,34],{34:90,37:D}),{32:[1,91]},{7:30,8:y,9:92,12:m,14:10,15:11,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p,27:26,29:27,30:28,31:29,33:31,35:v,36:_,42:32,47:b},{10:[1,93]},n(A,[2,55]),{10:[1,94]},n(A,C,{46:95,48:T,49:F,50:O,51:L,52:I,53:B,54:N,55:P,56:R}),n(Y,[2,42]),n(Y,[2,43]),n(w,[2,33],{34:96,37:D}),n(w,[2,32]),{7:97,14:10,15:11,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p},{10:[1,98]},n(A,[2,54]),{5:[2,3]},n(A,[2,50]),n(w,[2,31]),{28:[1,99],39:[2,37],40:[1,100]},n(A,[2,53]),{7:81,14:10,15:11,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p,38:101},{7:81,14:10,15:11,16:i,17:a,18:u,19:o,20:s,21:c,22:l,23:h,24:f,25:d,26:p,38:102},{39:[2,35]},{39:[2,36]}],defaultActions:{7:[2,1],41:[2,4],60:[2,2],61:[2,22],94:[2,3],101:[2,35],102:[2,36]},parseError:function(t,n){if(!n.recoverable){var e=function(t,n){this.message=t,this.hash=n};throw e.prototype=Error,new e(t,n)}this.trace(t)},parse:function(t){var n=this,e=[0],r=[null],i=[],a=this.table,u="",o=0,s=0,c=0,l=2,h=1,f=i.slice.call(arguments,1),d=Object.create(this.lexer),p={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(p.yy[g]=this.yy[g]);d.setInput(t,p.yy),p.yy.lexer=d,p.yy.parser=this,"undefined"==typeof d.yylloc&&(d.yylloc={});var y=d.yylloc;i.push(y);var m=d.options&&d.options.ranges;this.parseError="function"==typeof p.yy.parseError?p.yy.parseError:Object.getPrototypeOf(this).parseError;for(var v,_,b,x,w,A,k,E,M,S=function(){var t;return t=d.lex()||h,"number"!=typeof t&&(t=n.symbols_[t]||t),t},D={};;){if(b=e[e.length-1],this.defaultActions[b]?x=this.defaultActions[b]:((null===v||"undefined"==typeof v)&&(v=S()),x=a[b]&&a[b][v]),"undefined"==typeof x||!x.length||!x[0]){var C="";M=[];for(A in a[b])this.terminals_[A]&&A>l&&M.push("'"+this.terminals_[A]+"'");C=d.showPosition?"Parse error on line "+(o+1)+":\n"+d.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[v]||v)+"'":"Parse error on line "+(o+1)+": Unexpected "+(v==h?"end of input":"'"+(this.terminals_[v]||v)+"'"),this.parseError(C,{text:d.match,token:this.terminals_[v]||v,line:d.yylineno,loc:y,expected:M})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+v);switch(x[0]){case 1:e.push(v),r.push(d.yytext),i.push(d.yylloc),e.push(x[1]),v=null,_?(v=_,_=null):(s=d.yyleng,u=d.yytext,o=d.yylineno,y=d.yylloc,c>0&&c--);break;case 2:if(k=this.productions_[x[1]][1],D.$=r[r.length-k],D._$={first_line:i[i.length-(k||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(k||1)].first_column,last_column:i[i.length-1].last_column},m&&(D._$.range=[i[i.length-(k||1)].range[0],i[i.length-1].range[1]]),w=this.performAction.apply(D,[u,s,o,p.yy,x[1],r,i].concat(f)),"undefined"!=typeof w)return w;k&&(e=e.slice(0,-1*k*2),r=r.slice(0,-1*k),i=i.slice(0,-1*k)),e.push(this.productions_[x[1]][0]),r.push(D.$),i.push(D._$),E=a[e[e.length-2]][e[e.length-1]],e.push(E);break;case 3:return!0}}return!0}},$=function(){var t={EOF:1,parseError:function(t,n){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,n)},setInput:function(t,n){return this.yy=n||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t;var n=t.match(/(?:\r\n?|\n).*/g);return n?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var n=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===r.length?this.yylloc.first_column:0)+r[r.length-e.length].length-e[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),n=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+n+"^"},test_match:function(t,n){var e,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),r=t[0].match(/(?:\r\n?|\n).*/g),r&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,n,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF; - -this._input||(this.done=!0);var t,n,e,r;this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;an[0].length)){if(n=e,r=a,this.options.backtrack_lexer){if(t=this.test_match(e,i[a]),t!==!1)return t;if(this._backtrack){n=!1;continue}return!1}if(!this.options.flex)break}return n?(t=this.test_match(n,i[r]),t!==!1?t:!1):""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t?t:this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){var t=this.conditionStack.length-1;return t>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return t=this.conditionStack.length-1-Math.abs(t||0),t>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,n,e,r){switch(e){case 0:return"STYLE";case 1:return"LINKSTYLE";case 2:return"CLASSDEF";case 3:return"CLASS";case 4:return"CLICK";case 5:return 12;case 6:return 13;case 7:return 47;case 8:return 35;case 9:return 36;case 10:return"DIR";case 11:return"DIR";case 12:return"DIR";case 13:return"DIR";case 14:return"DIR";case 15:return"DIR";case 16:return 17;case 17:return 23;case 18:return 18;case 19:return 28;case 20:return 40;case 21:return 32;case 22:return 21;case 23:return 22;case 24:return"ARROW_CROSS";case 25:return 57;case 26:return"ARROW_CIRCLE";case 27:return 58;case 28:return 25;case 29:return 19;case 30:return 20;case 31:return 16;case 32:return"PIPE";case 33:return"PS";case 34:return"PE";case 35:return 37;case 36:return 39;case 37:return 8;case 38:return 10;case 39:return"QUOTE";case 40:return 24;case 41:return"NEWLINE";case 42:return 5}},rules:[/^(?:style\b)/,/^(?:linkStyle\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:click\b)/,/^(?:graph\b)/,/^(?:digraph\b)/,/^(?:subgraph\b)/,/^(?:node\b)/,/^(?:edge\b)/,/^(?:LR\b)/,/^(?:RL\b)/,/^(?:TB\b)/,/^(?:BT\b)/,/^(?:TD\b)/,/^(?:BR\b)/,/^(?:[0-9])/,/^(?:#)/,/^(?::)/,/^(?:;)/,/^(?:,)/,/^(?:=)/,/^(?:\*)/,/^(?:\.)/,/^(?:--[x])/,/^(?:->)/,/^(?:--[o])/,/^(?:--)/,/^(?:-)/,/^(?:\+)/,/^(?:=)/,/^(?:[\u0021-\u0027\u002A-\u002E\u003F\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC_])/,/^(?:\|)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\{)/,/^(?:\})/,/^(?:")/,/^(?:\s)/,/^(?:\n)/,/^(?:$)/],conditions:{INITIAL:{rules:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42],inclusive:!0}}};return t}();return U.lexer=$,t.prototype=U,U.Parser=t,new t}();"undefined"!=typeof t&&"undefined"!=typeof e&&(e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(n){n[1]||(console.log("Usage: "+n[0]+" FILE"),r.exit(1));var i=t("fs").readFileSync(t("path").normalize(n[1]),"utf8");return e.parser.parse(i)},"undefined"!=typeof n&&t.main===n&&e.main(r.argv.slice(1)))}).call(this,t("_process"))},{_process:106,fs:1,path:105}],119:[function(t,n,e){(function(r){"use strict";var i=function(){function t(){this.yy={}}var n=function(t,n,e,r){for(e=e||{},r=t.length;r--;e[t[r]]=n);return e},e=[1,4],r=[1,3],i=[1,5],a=[1,8,9,10,11,13,18,30,46,71,72,73,74,75,81,86,88,89,91,92,94,95,96,97,98],u=[2,2],o=[1,12],s=[1,13],c=[1,14],l=[1,15],h=[1,31],f=[1,33],d=[1,22],p=[1,34],g=[1,24],y=[1,25],m=[1,26],v=[1,27],_=[1,28],b=[1,38],x=[1,40],w=[1,35],A=[1,39],k=[1,45],E=[1,44],M=[1,36],S=[1,37],D=[1,41],C=[1,42],T=[1,43],F=[1,8,9,10,11,13,18,30,32,46,71,72,73,74,75,81,86,88,89,91,92,94,95,96,97,98],O=[1,53],L=[1,52],I=[1,54],B=[1,72],N=[1,80],P=[1,81],R=[1,66],j=[1,65],Y=[1,85],U=[1,84],$=[1,82],W=[1,83],z=[1,73],q=[1,68],G=[1,67],H=[1,63],V=[1,75],Z=[1,76],X=[1,77],K=[1,78],Q=[1,79],J=[1,70],tt=[1,69],nt=[8,9,11],et=[8,9,11,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64],rt=[1,115],it=[8,9,10,11,13,15,18,36,38,40,42,46,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,81,86,88,89,91,92,94,95,96,97,98],at=[8,9,10,11,12,13,15,16,17,18,30,32,36,37,38,39,40,41,42,43,46,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,71,72,73,74,75,78,81,84,86,88,89,91,92,94,95,96,97,98],ut=[1,117],ot=[1,118],st=[8,9,10,11,13,18,30,32,46,71,72,73,74,75,81,86,88,89,91,92,94,95,96,97,98],ct=[8,9,10,11,12,13,15,16,17,18,30,32,37,39,41,43,46,50,51,52,53,54,56,57,58,59,60,61,62,63,64,65,71,72,73,74,75,78,81,84,86,88,89,91,92,94,95,96,97,98],lt=[13,18,46,81,86,88,89,91,92,94,95,96,97,98],ht=[13,18,46,49,65,81,86,88,89,91,92,94,95,96,97,98],ft=[1,191],dt=[1,188],pt=[1,195],gt=[1,192],yt=[1,189],mt=[1,196],vt=[1,186],_t=[1,187],bt=[1,190],xt=[1,193],wt=[1,194],At=[1,213],kt=[8,9,11,86],Et=[8,9,10,11,46,71,80,81,84,86,88,89,90,91,92],Mt={trace:function(){},yy:{},symbols_:{error:2,mermaidDoc:3,graphConfig:4,document:5,line:6,statement:7,SEMI:8,NEWLINE:9,SPACE:10,EOF:11,GRAPH:12,DIR:13,FirstStmtSeperator:14,TAGEND:15,TAGSTART:16,UP:17,DOWN:18,ending:19,endToken:20,spaceList:21,spaceListNewline:22,verticeStatement:23,separator:24,styleStatement:25,linkStyleStatement:26,classDefStatement:27,classStatement:28,clickStatement:29,subgraph:30,text:31,end:32,vertex:33,link:34,alphaNum:35,SQS:36,SQE:37,PS:38,PE:39,"(-":40,"-)":41,DIAMOND_START:42,DIAMOND_STOP:43,alphaNumStatement:44,alphaNumToken:45,MINUS:46,linkStatement:47,arrowText:48,TESTSTR:49,"--":50,ARROW_POINT:51,ARROW_CIRCLE:52,ARROW_CROSS:53,ARROW_OPEN:54,"-.":55,DOTTED_ARROW_POINT:56,DOTTED_ARROW_CIRCLE:57,DOTTED_ARROW_CROSS:58,DOTTED_ARROW_OPEN:59,"==":60,THICK_ARROW_POINT:61,THICK_ARROW_CIRCLE:62,THICK_ARROW_CROSS:63,THICK_ARROW_OPEN:64,PIPE:65,textToken:66,STR:67,commentText:68,commentToken:69,keywords:70,STYLE:71,LINKSTYLE:72,CLASSDEF:73,CLASS:74,CLICK:75,textNoTags:76,textNoTagsToken:77,DEFAULT:78,stylesOpt:79,HEX:80,NUM:81,INTERPOLATE:82,commentStatement:83,PCT:84,style:85,COMMA:86,styleComponent:87,ALPHA:88,COLON:89,UNIT:90,BRKT:91,DOT:92,graphCodeTokens:93,PUNCTUATION:94,UNICODE_TEXT:95,PLUS:96,EQUALS:97,MULT:98,TAG_START:99,TAG_END:100,QUOTE:101,$accept:0,$end:1},terminals_:{2:"error",8:"SEMI",9:"NEWLINE",10:"SPACE",11:"EOF",12:"GRAPH",13:"DIR",15:"TAGEND",16:"TAGSTART",17:"UP",18:"DOWN",30:"subgraph",32:"end",36:"SQS",37:"SQE",38:"PS",39:"PE",40:"(-",41:"-)",42:"DIAMOND_START",43:"DIAMOND_STOP",46:"MINUS",49:"TESTSTR",50:"--",51:"ARROW_POINT",52:"ARROW_CIRCLE",53:"ARROW_CROSS",54:"ARROW_OPEN",55:"-.",56:"DOTTED_ARROW_POINT",57:"DOTTED_ARROW_CIRCLE",58:"DOTTED_ARROW_CROSS",59:"DOTTED_ARROW_OPEN",60:"==",61:"THICK_ARROW_POINT",62:"THICK_ARROW_CIRCLE",63:"THICK_ARROW_CROSS",64:"THICK_ARROW_OPEN",65:"PIPE",67:"STR",71:"STYLE",72:"LINKSTYLE",73:"CLASSDEF",74:"CLASS",75:"CLICK",78:"DEFAULT",80:"HEX",81:"NUM",82:"INTERPOLATE",84:"PCT",86:"COMMA",88:"ALPHA",89:"COLON",90:"UNIT",91:"BRKT",92:"DOT",94:"PUNCTUATION",95:"UNICODE_TEXT",96:"PLUS",97:"EQUALS",98:"MULT",99:"TAG_START",100:"TAG_END",101:"QUOTE"},productions_:[0,[3,2],[5,0],[5,2],[6,1],[6,1],[6,1],[6,1],[6,1],[4,2],[4,2],[4,4],[4,4],[4,4],[4,4],[4,4],[19,2],[19,1],[20,1],[20,1],[20,1],[14,1],[14,1],[14,2],[22,2],[22,2],[22,1],[22,1],[21,2],[21,1],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,5],[7,4],[24,1],[24,1],[24,1],[23,3],[23,1],[33,4],[33,5],[33,6],[33,7],[33,4],[33,5],[33,4],[33,5],[33,4],[33,5],[33,4],[33,5],[33,1],[33,2],[35,1],[35,2],[44,1],[44,1],[44,1],[44,1],[34,2],[34,3],[34,3],[34,1],[34,3],[34,3],[34,3],[34,3],[34,3],[34,3],[34,3],[34,3],[34,3],[34,3],[34,3],[34,3],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[48,3],[31,1],[31,2],[31,1],[68,1],[68,2],[70,1],[70,1],[70,1],[70,1],[70,1],[70,1],[70,1],[70,1],[70,1],[70,1],[70,1],[76,1],[76,2],[27,5],[27,5],[28,5],[29,5],[29,7],[29,5],[29,7],[25,5],[25,5],[26,5],[26,5],[26,9],[26,9],[26,7],[26,7],[83,3],[79,1],[79,3],[85,1],[85,2],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[69,1],[69,1],[66,1],[66,1],[66,1],[66,1],[66,1],[66,1],[66,1],[77,1],[77,1],[77,1],[77,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1]],performAction:function(t,n,e,r,i,a){var u=a.length-1;switch(i){case 2:this.$=[];break;case 3:a[u]!==[]&&a[u-1].push(a[u]),this.$=a[u-1];break;case 4:case 57:case 59:case 60:case 92:case 94:case 95:case 108:this.$=a[u];break;case 11:r.setDirection(a[u-1]),this.$=a[u-1];break;case 12:r.setDirection("LR"),this.$=a[u-1];break;case 13:r.setDirection("RL"),this.$=a[u-1];break;case 14:r.setDirection("BT"),this.$=a[u-1];break;case 15:r.setDirection("TB"),this.$=a[u-1];break;case 30:this.$=a[u-1];break;case 31:case 32:case 33:case 34:case 35:this.$=[];break;case 36:this.$=r.addSubGraph(a[u-1],a[u-3]);break;case 37:this.$=r.addSubGraph(a[u-1],void 0);break;case 41:r.addLink(a[u-2],a[u],a[u-1]),this.$=[a[u-2],a[u]];break;case 42:this.$=[a[u]];break;case 43:this.$=a[u-3],r.addVertex(a[u-3],a[u-1],"square");break;case 44:this.$=a[u-4],r.addVertex(a[u-4],a[u-2],"square");break;case 45:this.$=a[u-5],r.addVertex(a[u-5],a[u-2],"circle");break;case 46:this.$=a[u-6],r.addVertex(a[u-6],a[u-3],"circle");break;case 47:this.$=a[u-3],r.addVertex(a[u-3],a[u-1],"ellipse");break;case 48:this.$=a[u-4],r.addVertex(a[u-4],a[u-2],"ellipse");break;case 49:this.$=a[u-3],r.addVertex(a[u-3],a[u-1],"round");break;case 50:this.$=a[u-4],r.addVertex(a[u-4],a[u-2],"round");break;case 51:this.$=a[u-3],r.addVertex(a[u-3],a[u-1],"diamond");break;case 52:this.$=a[u-4],r.addVertex(a[u-4],a[u-2],"diamond");break;case 53:this.$=a[u-3],r.addVertex(a[u-3],a[u-1],"odd");break;case 54:this.$=a[u-4],r.addVertex(a[u-4],a[u-2],"odd");break;case 55:this.$=a[u],r.addVertex(a[u]);break;case 56:this.$=a[u-1],r.addVertex(a[u-1]);break;case 58:case 93:case 96:case 109:this.$=a[u-1]+""+a[u];break;case 61:this.$="v";break;case 62:this.$="-";break;case 63:a[u-1].text=a[u],this.$=a[u-1];break;case 64:case 65:a[u-2].text=a[u-1],this.$=a[u-2];break;case 66:this.$=a[u];break;case 67:this.$={type:"arrow",stroke:"normal",text:a[u-1]};break;case 68:this.$={type:"arrow_circle",stroke:"normal",text:a[u-1]};break;case 69:this.$={type:"arrow_cross",stroke:"normal",text:a[u-1]};break;case 70:this.$={type:"arrow_open",stroke:"normal",text:a[u-1]};break;case 71:this.$={type:"arrow",stroke:"dotted",text:a[u-1]};break;case 72:this.$={type:"arrow_circle",stroke:"dotted",text:a[u-1]};break;case 73:this.$={type:"arrow_cross",stroke:"dotted",text:a[u-1]};break;case 74:this.$={type:"arrow_open",stroke:"dotted",text:a[u-1]};break;case 75:this.$={type:"arrow",stroke:"thick",text:a[u-1]};break;case 76:this.$={type:"arrow_circle",stroke:"thick",text:a[u-1]};break;case 77:this.$={type:"arrow_cross",stroke:"thick",text:a[u-1]};break;case 78:this.$={type:"arrow_open",stroke:"thick",text:a[u-1]};break;case 79:this.$={type:"arrow",stroke:"normal"};break;case 80:this.$={type:"arrow_circle",stroke:"normal"};break;case 81:this.$={type:"arrow_cross",stroke:"normal"};break;case 82:this.$={type:"arrow_open",stroke:"normal"};break;case 83:this.$={type:"arrow",stroke:"dotted"};break;case 84:this.$={type:"arrow_circle",stroke:"dotted"};break;case 85:this.$={type:"arrow_cross",stroke:"dotted"};break;case 86:this.$={type:"arrow_open",stroke:"dotted"};break;case 87:this.$={type:"arrow",stroke:"thick"};break;case 88:this.$={type:"arrow_circle",stroke:"thick"};break;case 89:this.$={type:"arrow_cross",stroke:"thick"};break;case 90:this.$={type:"arrow_open",stroke:"thick"};break;case 91:this.$=a[u-1];break;case 110:case 111:this.$=a[u-4],r.addClass(a[u-2],a[u]);break;case 112:this.$=a[u-4],r.setClass(a[u-2],a[u]);break;case 113:this.$=a[u-4],r.setClickEvent(a[u-2],a[u],void 0,void 0);break;case 114:this.$=a[u-6],r.setClickEvent(a[u-4],a[u-2],void 0,a[u]);break;case 115:this.$=a[u-4],r.setClickEvent(a[u-2],void 0,a[u],void 0);break;case 116:this.$=a[u-6],r.setClickEvent(a[u-4],void 0,a[u-2],a[u]);break;case 117:this.$=a[u-4],r.addVertex(a[u-2],void 0,void 0,a[u]);break;case 118:case 119:case 120:this.$=a[u-4],r.updateLink(a[u-2],a[u]);break;case 121:case 122:this.$=a[u-8],r.updateLinkInterpolate(a[u-6],a[u-2]),r.updateLink(a[u-6],a[u]);break;case 123:case 124:this.$=a[u-6],r.updateLinkInterpolate(a[u-4],a[u]);break;case 126:this.$=[a[u]];break;case 127:a[u-2].push(a[u]),this.$=a[u-2];break;case 129:this.$=a[u-1]+a[u]}},table:[{3:1,4:2,9:e,10:r,12:i},{1:[3]},n(a,u,{5:6}),{4:7,9:e,10:r,12:i},{4:8,9:e,10:r,12:i},{10:[1,9]},{1:[2,1],6:10,7:11,8:o,9:s,10:c,11:l,13:h,18:f,23:16,25:17,26:18,27:19,28:20,29:21,30:d,33:23,35:29,44:30,45:32,46:p,71:g,72:y,73:m,74:v,75:_,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},n(a,[2,9]),n(a,[2,10]),{13:[1,46],15:[1,47],16:[1,48],17:[1,49],18:[1,50]},n(F,[2,3]),n(F,[2,4]),n(F,[2,5]),n(F,[2,6]),n(F,[2,7]),n(F,[2,8]),{8:O,9:L,11:I,24:51},{8:O,9:L,11:I,24:55},{8:O,9:L,11:I,24:56},{8:O,9:L,11:I,24:57},{8:O,9:L,11:I,24:58},{8:O,9:L,11:I,24:59},{8:O,9:L,10:B,11:I,12:N,13:P,15:R,16:j,17:Y,18:U,24:61,30:$,31:60,32:W,45:71,46:z,50:q,60:G,66:62,67:H,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},n(nt,[2,42],{34:86,47:87,50:[1,88],51:[1,91],52:[1,92],53:[1,93],54:[1,94],55:[1,89],56:[1,95],57:[1,96],58:[1,97],59:[1,98],60:[1,90],61:[1,99],62:[1,100],63:[1,101],64:[1,102]}),{10:[1,103]},{10:[1,104]},{10:[1,105]},{10:[1,106]},{10:[1,107]},n(et,[2,55],{45:32,21:113,44:114,10:rt,13:h,15:[1,112],18:f,36:[1,108],38:[1,109],40:[1,110],42:[1,111],46:p,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T}),n(it,[2,57]),n(it,[2,59]),n(it,[2,60]),n(it,[2,61]),n(it,[2,62]),n(at,[2,154]),n(at,[2,155]),n(at,[2,156]),n(at,[2,157]),n(at,[2,158]),n(at,[2,159]),n(at,[2,160]),n(at,[2,161]),n(at,[2,162]),n(at,[2,163]),n(at,[2,164]),{8:ut,9:ot,10:rt,14:116,21:119},{8:ut,9:ot,10:rt,14:120,21:119},{8:ut,9:ot,10:rt,14:121,21:119},{8:ut,9:ot,10:rt,14:122,21:119},{8:ut,9:ot,10:rt,14:123,21:119},n(F,[2,30]),n(F,[2,38]),n(F,[2,39]),n(F,[2,40]),n(F,[2,31]),n(F,[2,32]),n(F,[2,33]),n(F,[2,34]),n(F,[2,35]),{8:O,9:L,10:B,11:I,12:N,13:P,15:R,16:j,17:Y,18:U,24:124,30:$,32:W,45:71,46:z,50:q,60:G,66:125,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},n(st,u,{5:126}),n(ct,[2,92]),n(ct,[2,94]),n(ct,[2,143]),n(ct,[2,144]),n(ct,[2,145]),n(ct,[2,146]),n(ct,[2,147]),n(ct,[2,148]),n(ct,[2,149]),n(ct,[2,150]),n(ct,[2,151]),n(ct,[2,152]),n(ct,[2,153]),n(ct,[2,97]),n(ct,[2,98]),n(ct,[2,99]),n(ct,[2,100]),n(ct,[2,101]),n(ct,[2,102]),n(ct,[2,103]),n(ct,[2,104]),n(ct,[2,105]),n(ct,[2,106]),n(ct,[2,107]),{13:h,18:f,33:127,35:29,44:30,45:32,46:p,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},n(lt,[2,66],{48:128,49:[1,129],65:[1,130]}),{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,31:131,32:W,45:71,46:z,50:q,60:G,66:62,67:H,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,31:132,32:W,45:71,46:z,50:q,60:G,66:62,67:H,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,31:133,32:W,45:71,46:z,50:q,60:G,66:62,67:H,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},n(ht,[2,79]),n(ht,[2,80]),n(ht,[2,81]),n(ht,[2,82]),n(ht,[2,83]),n(ht,[2,84]),n(ht,[2,85]),n(ht,[2,86]),n(ht,[2,87]),n(ht,[2,88]),n(ht,[2,89]),n(ht,[2,90]),{13:h,18:f,35:134,44:30,45:32,46:p,80:[1,135],81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{78:[1,136],81:[1,137]},{13:h,18:f,35:139,44:30,45:32,46:p,78:[1,138],81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{13:h,18:f,35:140,44:30,45:32,46:p,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{13:h,18:f,35:141,44:30,45:32,46:p,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,31:142,32:W,45:71,46:z,50:q,60:G,66:62,67:H,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,31:144,32:W,38:[1,143],45:71,46:z,50:q,60:G,66:62,67:H,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,31:145,32:W,45:71,46:z,50:q,60:G,66:62,67:H,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,31:146,32:W,45:71,46:z,50:q,60:G,66:62,67:H,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,31:147,32:W,45:71,46:z,50:q,60:G,66:62,67:H,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},n(et,[2,56]),n(it,[2,58]),n(et,[2,29],{21:148,10:rt}),n(a,[2,11]),n(a,[2,21]),n(a,[2,22]),{9:[1,149]},n(a,[2,12]),n(a,[2,13]),n(a,[2,14]),n(a,[2,15]),n(st,u,{5:150}),n(ct,[2,93]),{6:10,7:11,8:o,9:s,10:c,11:l,13:h,18:f,23:16,25:17,26:18,27:19,28:20,29:21,30:d,32:[1,151],33:23,35:29,44:30,45:32,46:p,71:g,72:y,73:m,74:v,75:_,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},n(nt,[2,41]),n(lt,[2,63],{10:[1,152]}),{10:[1,153]},{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,31:154,32:W,45:71,46:z,50:q,60:G,66:62,67:H,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,32:W,45:71,46:z,50:q,51:[1,155],52:[1,156],53:[1,157],54:[1,158],60:G,66:125,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,32:W,45:71,46:z,50:q,56:[1,159],57:[1,160],58:[1,161],59:[1,162],60:G,66:125,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,32:W,45:71,46:z,50:q,60:G,61:[1,163],62:[1,164],63:[1,165],64:[1,166],66:125,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:[1,167],13:h,18:f,44:114,45:32,46:p,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:[1,168]},{10:[1,169]},{10:[1,170]},{10:[1,171]},{10:[1,172],13:h,18:f,44:114,45:32,46:p,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:[1,173],13:h,18:f,44:114,45:32,46:p,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:[1,174],13:h,18:f,44:114,45:32,46:p,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,32:W,37:[1,175],45:71,46:z,50:q,60:G,66:125,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,31:176,32:W,45:71,46:z,50:q,60:G,66:62,67:H,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,32:W,39:[1,177],45:71,46:z,50:q,60:G,66:125,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,32:W,41:[1,178],45:71,46:z,50:q,60:G,66:125,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,32:W,43:[1,179],45:71,46:z,50:q,60:G,66:125,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,32:W,37:[1,180],45:71,46:z,50:q,60:G,66:125,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},n(et,[2,28]),n(a,[2,23]),{6:10,7:11,8:o,9:s,10:c,11:l,13:h,18:f,23:16,25:17,26:18,27:19,28:20,29:21,30:d,32:[1,181],33:23,35:29,44:30,45:32,46:p,71:g,72:y,73:m,74:v,75:_,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},n(F,[2,37]),n(lt,[2,65]),n(lt,[2,64]),{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,32:W,45:71,46:z,50:q,60:G,65:[1,182],66:125,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},n(lt,[2,67]),n(lt,[2,68]),n(lt,[2,69]),n(lt,[2,70]),n(lt,[2,71]),n(lt,[2,72]),n(lt,[2,73]),n(lt,[2,74]),n(lt,[2,75]),n(lt,[2,76]),n(lt,[2,77]),n(lt,[2,78]),{10:ft,46:dt,71:pt,79:183,80:gt,81:yt,84:mt,85:184,87:185,88:vt,89:_t,90:bt,91:xt,92:wt},{10:ft,46:dt,71:pt,79:197,80:gt,81:yt,84:mt,85:184,87:185,88:vt,89:_t,90:bt,91:xt,92:wt},{10:ft,46:dt,71:pt,79:198,80:gt,81:yt,82:[1,199],84:mt,85:184,87:185,88:vt,89:_t,90:bt,91:xt,92:wt},{10:ft,46:dt,71:pt,79:200,80:gt,81:yt,82:[1,201],84:mt,85:184,87:185,88:vt,89:_t,90:bt,91:xt,92:wt},{10:ft,46:dt,71:pt,79:202,80:gt,81:yt,84:mt,85:184,87:185,88:vt,89:_t,90:bt,91:xt,92:wt},{10:ft,46:dt,71:pt,79:203,80:gt,81:yt,84:mt,85:184,87:185,88:vt,89:_t,90:bt,91:xt,92:wt},{13:h,18:f,35:204,44:30,45:32,46:p,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{13:h,18:f,35:205,44:30,45:32,46:p,67:[1,206],81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},n(et,[2,43],{21:207,10:rt}),{10:B,12:N,13:P,15:R,16:j,17:Y,18:U,30:$,32:W,39:[1,208],45:71,46:z,50:q,60:G,66:125,70:74,71:V,72:Z,73:X,74:K,75:Q,77:64,78:J,81:b,84:tt,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},n(et,[2,49],{21:209,10:rt}),n(et,[2,47],{21:210,10:rt}),n(et,[2,51],{21:211,10:rt}),n(et,[2,53],{21:212,10:rt}),n(F,[2,36]),n([10,13,18,46,81,86,88,89,91,92,94,95,96,97,98],[2,91]),n(nt,[2,117],{86:At}),n(kt,[2,126],{87:214,10:ft,46:dt,71:pt,80:gt,81:yt,84:mt,88:vt,89:_t,90:bt,91:xt,92:wt}),n(Et,[2,128]),n(Et,[2,130]),n(Et,[2,131]),n(Et,[2,132]),n(Et,[2,133]),n(Et,[2,134]),n(Et,[2,135]),n(Et,[2,136]),n(Et,[2,137]),n(Et,[2,138]),n(Et,[2,139]),n(Et,[2,140]),n(nt,[2,118],{86:At}),n(nt,[2,119],{86:At}),{10:[1,215]},n(nt,[2,120],{86:At}),{10:[1,216]},n(nt,[2,110],{86:At}),n(nt,[2,111],{86:At}),n(nt,[2,112],{45:32,44:114,13:h,18:f,46:p,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T}),n(nt,[2,113],{45:32,44:114,10:[1,217],13:h,18:f,46:p,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T}),n(nt,[2,115],{10:[1,218]}),n(et,[2,44]),{39:[1,219]},n(et,[2,50]),n(et,[2,48]),n(et,[2,52]),n(et,[2,54]),{10:ft,46:dt,71:pt,80:gt,81:yt,84:mt,85:220,87:185,88:vt,89:_t,90:bt,91:xt,92:wt},n(Et,[2,129]),{13:h,18:f,35:221,44:30,45:32,46:p,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{13:h,18:f,35:222,44:30,45:32,46:p,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T},{67:[1,223]},{67:[1,224]},n(et,[2,45],{21:225,10:rt}),n(kt,[2,127],{87:214,10:ft,46:dt,71:pt,80:gt,81:yt,84:mt,88:vt,89:_t,90:bt,91:xt,92:wt}),n(nt,[2,123],{45:32,44:114,10:[1,226],13:h,18:f,46:p,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T}),n(nt,[2,124],{45:32,44:114,10:[1,227],13:h,18:f,46:p,81:b,86:x,88:w,89:A,91:k,92:E,94:M,95:S,96:D,97:C,98:T}),n(nt,[2,114]),n(nt,[2,116]),n(et,[2,46]),{10:ft,46:dt,71:pt,79:228,80:gt,81:yt,84:mt,85:184,87:185,88:vt,89:_t,90:bt,91:xt,92:wt},{10:ft,46:dt,71:pt,79:229,80:gt,81:yt,84:mt,85:184,87:185,88:vt,89:_t,90:bt,91:xt,92:wt},n(nt,[2,121],{86:At}),n(nt,[2,122],{86:At})],defaultActions:{},parseError:function(t,n){if(!n.recoverable){var e=function(t,n){this.message=t,this.hash=n};throw e.prototype=Error,new e(t,n)}this.trace(t)},parse:function(t){var n=this,e=[0],r=[null],i=[],a=this.table,u="",o=0,s=0,c=0,l=2,h=1,f=i.slice.call(arguments,1),d=Object.create(this.lexer),p={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(p.yy[g]=this.yy[g]);d.setInput(t,p.yy),p.yy.lexer=d,p.yy.parser=this,"undefined"==typeof d.yylloc&&(d.yylloc={});var y=d.yylloc;i.push(y);var m=d.options&&d.options.ranges;this.parseError="function"==typeof p.yy.parseError?p.yy.parseError:Object.getPrototypeOf(this).parseError;for(var v,_,b,x,w,A,k,E,M,S=function(){var t;return t=d.lex()||h,"number"!=typeof t&&(t=n.symbols_[t]||t),t},D={};;){if(b=e[e.length-1],this.defaultActions[b]?x=this.defaultActions[b]:((null===v||"undefined"==typeof v)&&(v=S()),x=a[b]&&a[b][v]),"undefined"==typeof x||!x.length||!x[0]){var C="";M=[];for(A in a[b])this.terminals_[A]&&A>l&&M.push("'"+this.terminals_[A]+"'");C=d.showPosition?"Parse error on line "+(o+1)+":\n"+d.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[v]||v)+"'":"Parse error on line "+(o+1)+": Unexpected "+(v==h?"end of input":"'"+(this.terminals_[v]||v)+"'"),this.parseError(C,{text:d.match,token:this.terminals_[v]||v,line:d.yylineno,loc:y,expected:M})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+v);switch(x[0]){case 1:e.push(v),r.push(d.yytext),i.push(d.yylloc),e.push(x[1]),v=null,_?(v=_,_=null):(s=d.yyleng,u=d.yytext,o=d.yylineno,y=d.yylloc,c>0&&c--);break;case 2:if(k=this.productions_[x[1]][1],D.$=r[r.length-k],D._$={first_line:i[i.length-(k||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(k||1)].first_column,last_column:i[i.length-1].last_column},m&&(D._$.range=[i[i.length-(k||1)].range[0],i[i.length-1].range[1]]),w=this.performAction.apply(D,[u,s,o,p.yy,x[1],r,i].concat(f)),"undefined"!=typeof w)return w;k&&(e=e.slice(0,-1*k*2),r=r.slice(0,-1*k),i=i.slice(0,-1*k)),e.push(this.productions_[x[1]][0]),r.push(D.$),i.push(D._$),E=a[e[e.length-2]][e[e.length-1]],e.push(E);break;case 3:return!0}}return!0}},St=function(){var t={EOF:1,parseError:function(t,n){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,n)},setInput:function(t,n){return this.yy=n||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t;var n=t.match(/(?:\r\n?|\n).*/g);return n?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var n=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===r.length?this.yylloc.first_column:0)+r[r.length-e.length].length-e[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match; - -return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),n=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+n+"^"},test_match:function(t,n){var e,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),r=t[0].match(/(?:\r\n?|\n).*/g),r&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,n,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var t,n,e,r;this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;an[0].length)){if(n=e,r=a,this.options.backtrack_lexer){if(t=this.test_match(e,i[a]),t!==!1)return t;if(this._backtrack){n=!1;continue}return!1}if(!this.options.flex)break}return n?(t=this.test_match(n,i[r]),t!==!1?t:!1):""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t?t:this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){var t=this.conditionStack.length-1;return t>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return t=this.conditionStack.length-1-Math.abs(t||0),t>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,n,e,r){switch(e){case 0:break;case 1:this.begin("string");break;case 2:this.popState();break;case 3:return"STR";case 4:return 71;case 5:return 78;case 6:return 72;case 7:return 82;case 8:return 73;case 9:return 74;case 10:return 75;case 11:return 12;case 12:return 30;case 13:return 32;case 14:return 13;case 15:return 13;case 16:return 13;case 17:return 13;case 18:return 13;case 19:return 13;case 20:return 81;case 21:return 91;case 22:return 89;case 23:return 8;case 24:return 86;case 25:return 98;case 26:return 16;case 27:return 15;case 28:return 17;case 29:return 18;case 30:return 53;case 31:return 51;case 32:return 52;case 33:return 54;case 34:return 58;case 35:return 56;case 36:return 57;case 37:return 59;case 38:return 58;case 39:return 56;case 40:return 57;case 41:return 59;case 42:return 63;case 43:return 61;case 44:return 62;case 45:return 64;case 46:return 50;case 47:return 55;case 48:return 60;case 49:return 40;case 50:return 41;case 51:return 46;case 52:return 92;case 53:return 96;case 54:return 84;case 55:return 97;case 56:return 97;case 57:return 88;case 58:return 94;case 59:return 95;case 60:return 65;case 61:return 38;case 62:return 39;case 63:return 36;case 64:return 37;case 65:return 42;case 66:return 43;case 67:return 101;case 68:return 9;case 69:return 10;case 70:return 11}},rules:[/^(?:%%[^\n]*)/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:click\b)/,/^(?:graph\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:LR\b)/,/^(?:RL\b)/,/^(?:TB\b)/,/^(?:BT\b)/,/^(?:TD\b)/,/^(?:BR\b)/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:v\b)/,/^(?:\s*--[x]\s*)/,/^(?:\s*-->\s*)/,/^(?:\s*--[o]\s*)/,/^(?:\s*---\s*)/,/^(?:\s*-\.-[x]\s*)/,/^(?:\s*-\.->\s*)/,/^(?:\s*-\.-[o]\s*)/,/^(?:\s*-\.-\s*)/,/^(?:\s*.-[x]\s*)/,/^(?:\s*\.->\s*)/,/^(?:\s*\.-[o]\s*)/,/^(?:\s*\.-\s*)/,/^(?:\s*==[x]\s*)/,/^(?:\s*==>\s*)/,/^(?:\s*==[o]\s*)/,/^(?:\s*==[\=]\s*)/,/^(?:\s*--\s*)/,/^(?:\s*-\.\s*)/,/^(?:\s*==\s*)/,/^(?:\(-)/,/^(?:-\))/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:[A-Za-z]+)/,/^(?:[!"#$%&'*+,-.`?\\_\/])/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\|)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\{)/,/^(?:\})/,/^(?:")/,/^(?:\n+)/,/^(?:\s)/,/^(?:$)/],conditions:{string:{rules:[2,3],inclusive:!1},INITIAL:{rules:[0,1,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70],inclusive:!0}}};return t}();return Mt.lexer=St,t.prototype=Mt,Mt.Parser=t,new t}();"undefined"!=typeof t&&"undefined"!=typeof e&&(e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(n){n[1]||(console.log("Usage: "+n[0]+" FILE"),r.exit(1));var i=t("fs").readFileSync(t("path").normalize(n[1]),"utf8");return e.parser.parse(i)},"undefined"!=typeof n&&t.main===n&&e.main(r.argv.slice(1)))}).call(this,t("_process"))},{_process:106,fs:1,path:105}],120:[function(t,n,e){(function(n){"use strict";var r=t("moment"),i=t("../../logger"),a=new i.Log,u="",o="",s=[],c=[],l="";e.clear=function(){s=[],c=[],l="",o="",g=0,h=void 0,f=void 0,_=[]},e.setDateFormat=function(t){u=t},e.getDateFormat=function(){return u},e.setTitle=function(t){o=t},e.getTitle=function(){return o},e.addSection=function(t){l=t,s.push(t)},e.getTasks=function(){for(var t=x(),n=10,e=0;!t&&n>e;)t=x(),e++;return c=_};var h,f,d=function(t,n,i){i=i.trim();var u=/^after\s+([\d\w\-]+)/,o=u.exec(i.trim());if(null!==o){var s=e.findTaskById(o[1]);if("undefined"==typeof s){var c=new Date;return c.setHours(0,0,0,0),c}return s.endTime}return r(i,n.trim(),!0).isValid()?r(i,n.trim(),!0).toDate():(a.debug("Invalid date:"+i),a.debug("With date format:"+n.trim()),new Date)},p=function(t,n,e){if(e=e.trim(),r(e,n.trim(),!0).isValid())return r(e,n.trim()).toDate();var i=r(t),a=/^([\d]+)([wdhms])/,u=a.exec(e.trim());if(null!==u){switch(u[2]){case"s":i.add(u[1],"seconds");break;case"m":i.add(u[1],"minutes");break;case"h":i.add(u[1],"hours");break;case"d":i.add(u[1],"days");break;case"w":i.add(u[1],"weeks")}return i.toDate()}return i.toDate()},g=0,y=function(t){return"undefined"==typeof t?(g+=1,"task"+g):t},m=function(t,n){var r;r=":"===n.substr(0,1)?n.substr(1,n.length):n;for(var i=r.split(","),a={},u=e.getDateFormat(),o=!0;o;)o=!1,i[0].match(/^\s*active\s*$/)&&(a.active=!0,i.shift(1),o=!0),i[0].match(/^\s*done\s*$/)&&(a.done=!0,i.shift(1),o=!0),i[0].match(/^\s*crit\s*$/)&&(a.crit=!0,i.shift(1),o=!0);var s;for(s=0;se-n?e+i+1.5*u.leftPadding>o?n+r-5:e+r+5:(e-n)/2+n+r}).attr("y",function(t,r){return r*n+u.barHeight/2+(u.fontSize/2-2)+e}).attr("text-height",i).attr("class",function(t){for(var n=w(t.startTime),e=w(t.endTime),r=this.getBBox().width,i=0,a=0;ae-n?e+r+1.5*u.leftPadding>o?"taskTextOutsideLeft taskTextOutside"+i+" "+s:"taskTextOutsideRight taskTextOutside"+i+" "+s:"taskText taskText"+i+" "+s})}function l(t,n,e,a){var o,s=[[".%L",function(t){return t.getMilliseconds()}],[":%S",function(t){return t.getSeconds()}],["h1 %I:%M",function(t){return t.getMinutes()}]],c=[["%Y",function(){return!0}]],l=[["%I:%M",function(t){return t.getHours()}],["%a %d",function(t){return t.getDay()&&1!=t.getDate()}],["%b %d",function(t){return 1!=t.getDate()}],["%B",function(t){return t.getMonth()}]];"undefined"!=typeof u.axisFormatter&&(l=[],u.axisFormatter.forEach(function(t){var n=[];n[0]=t[0],n[1]=t[1],l.push(n)})),o=s.concat(l).concat(c);var h=i.svg.axis().scale(w).orient("bottom").tickSize(-a+n+u.gridLineStartPadding,0,0).tickFormat(i.time.format.multi(o));r>7&&230>r&&(h=h.ticks(i.time.monday.range)),_.append("g").attr("class","grid").attr("transform","translate("+t+", "+(a-50)+")").call(h).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10).attr("dy","1em")}function h(t,n){for(var e=[],r=0,i=0;i0))return i[1]*t/2+n;for(var u=0;a>u;u++)return r+=e[a-1][1],i[1]*t/2+r*t+n}).attr("class",function(t){for(var n=0;nr;++r)n.hasOwnProperty(t[r])||(n[t[r]]=!0,e.push(t[r]));return e}function p(t){for(var n=t.length,e={};n;)e[t[--n]]=(e[t[n]]||0)+1;return e}function g(t,n){return p(n)[t]||0}e.yy.clear(),e.parse(t);var y=document.getElementById(n);o=y.parentElement.offsetWidth,"undefined"==typeof o&&(o=1200),"undefined"!=typeof u.useWidth&&(o=u.useWidth);var m=e.yy.getTasks(),v=m.length*(u.barHeight+u.barGap)+2*u.topPadding;y.setAttribute("height","100%"),y.setAttribute("viewBox","0 0 "+o+" "+v);var _=i.select("#"+n),b=i.min(m,function(t){return t.startTime}),x=i.max(m,function(t){return t.endTime}),w=i.time.scale().domain([i.min(m,function(t){return t.startTime}),i.max(m,function(t){return t.endTime})]).rangeRound([0,o-u.leftPadding-u.rightPadding]),A=[];r=a.duration(x-b).asDays();for(var k=0;kl&&M.push("'"+this.terminals_[A]+"'");C=d.showPosition?"Parse error on line "+(o+1)+":\n"+d.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[v]||v)+"'":"Parse error on line "+(o+1)+": Unexpected "+(v==h?"end of input":"'"+(this.terminals_[v]||v)+"'"),this.parseError(C,{text:d.match,token:this.terminals_[v]||v,line:d.yylineno,loc:y,expected:M})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+v);switch(x[0]){case 1:e.push(v),r.push(d.yytext),i.push(d.yylloc),e.push(x[1]),v=null,_?(v=_,_=null):(s=d.yyleng,u=d.yytext,o=d.yylineno,y=d.yylloc,c>0&&c--);break;case 2:if(k=this.productions_[x[1]][1],D.$=r[r.length-k],D._$={first_line:i[i.length-(k||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(k||1)].first_column,last_column:i[i.length-1].last_column},m&&(D._$.range=[i[i.length-(k||1)].range[0],i[i.length-1].range[1]]),w=this.performAction.apply(D,[u,s,o,p.yy,x[1],r,i].concat(f)),"undefined"!=typeof w)return w;k&&(e=e.slice(0,-1*k*2),r=r.slice(0,-1*k),i=i.slice(0,-1*k)),e.push(this.productions_[x[1]][0]),r.push(D.$),i.push(D._$),E=a[e[e.length-2]][e[e.length-1]],e.push(E);break;case 3:return!0}}return!0}},s=function(){var t={EOF:1,parseError:function(t,n){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,n)},setInput:function(t,n){return this.yy=n||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t;var n=t.match(/(?:\r\n?|\n).*/g);return n?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var n=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===r.length?this.yylloc.first_column:0)+r[r.length-e.length].length-e[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),n=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+n+"^"},test_match:function(t,n){var e,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),r=t[0].match(/(?:\r\n?|\n).*/g),r&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,n,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var t,n,e,r;this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;an[0].length)){if(n=e,r=a,this.options.backtrack_lexer){if(t=this.test_match(e,i[a]),t!==!1)return t;if(this._backtrack){n=!1;continue}return!1}if(!this.options.flex)break}return n?(t=this.test_match(n,i[r]),t!==!1?t:!1):""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t?t:this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){var t=this.conditionStack.length-1;return t>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return t=this.conditionStack.length-1-Math.abs(t||0),t>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,n,e,r){switch(e){case 0:return 10;case 1:break;case 2:break;case 3:break;case 4:return 4;case 5:return 11;case 6:return"date";case 7:return 12;case 8:return 13;case 9:return 14;case 10:return 15;case 11:return":";case 12:return 6;case 13:return"INVALID"}},rules:[/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{INITIAL:{rules:[0,1,2,3,4,5,6,7,8,9,10,11,12,13],inclusive:!0}}};return t}();return o.lexer=s,t.prototype=o,o.Parser=t,new t}();"undefined"!=typeof t&&"undefined"!=typeof e&&(e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(n){n[1]||(console.log("Usage: "+n[0]+" FILE"),r.exit(1));var i=t("fs").readFileSync(t("path").normalize(n[1]),"utf8");return e.parser.parse(i)},"undefined"!=typeof n&&t.main===n&&e.main(r.argv.slice(1)))}).call(this,t("_process"))},{_process:106,fs:1,path:105}],123:[function(t,n,e){"use strict";function r(t,n){return Math.floor(Math.random()*(n-t))+t}function i(){for(var t="0123456789abcdef",n="",e=0;7>e;e++)n+=t[r(0,16)];return n}function a(t,n){var e,r=!0;t:for(;r;){var i=t,u=n;for(r=!1,h.debug("Entering isfastforwardable:",i.id,u.id);i.seq<=u.seq&&i!=u&&null!=u.parent;){if(Array.isArray(u.parent)){if(h.debug("In merge commit:",u.parent),e=a(i,f[u.parent[0]]))return e;t=i,n=f[u.parent[1]],r=!0;continue t}u=f[u.parent]}return h.debug(i.id,u.id),i.id==u.id}}function u(t,n){var e=t.seq,r=n.seq;return e>r?a(n,t):!1}function o(t,n,e){var r=l.find(t,n);if(r){var i=l.indexOf(t,l.find(t,n));t.splice(i,1,e)}else t.push(e)}function s(t){var n=l.maxBy(t,"seq"),e="";l.each(t,function(t){e+=t==n?" *":" |"});var r=[e,n.id,n.seq];if(l.each(p,function(t,e){t==n.id&&r.push(e)}),h.debug(r.join(" ")),Array.isArray(n.parent)){var i=f[n.parent[0]];o(t,n,i),t.push(f[n.parent[1]])}else{if(null==n.parent)return;var a=f[n.parent];o(t,n,a)}t=l.uniqBy(t,"id"),s(t)}var c=t("../../logger"),l=t("lodash"),h=new c.Log(1),f={},d=null,p={master:d},g="master",y="LR",m=0;e.setDirection=function(t){y=t};var v={};e.setOptions=function(t){h.debug("options str",t),t=t&&t.trim(),t=t||"{}";try{v=JSON.parse(t)}catch(n){h.error("error while parsing gitGraph options",n.message)}},e.getOptions=function(){return v},e.commit=function(t){var n={id:i(),message:t,seq:m++,parent:null==d?null:d.id};d=n,f[n.id]=n,p[g]=n.id,h.debug("in pushCommit "+n.id)},e.branch=function(t){p[t]=null!=d?d.id:null,h.debug("in createBranch")},e.merge=function(t){var n=f[p[g]],e=f[p[t]];if(u(n,e))return void h.debug("Already merged");if(a(n,e))p[g]=p[t],d=f[p[g]];else{var r={id:i(),message:"merged branch "+t+" into "+g,seq:m++,parent:[null==d?null:d.id,p[t]]};d=r,f[r.id]=r,p[g]=r.id}h.debug(p),h.debug("in mergeBranch")},e.checkout=function(t){h.debug("in checkout"),g=t;var n=p[g];d=f[n]},e.reset=function(t){h.debug("in reset",t);var n=t.split(":")[0],e=parseInt(t.split(":")[1]),r="HEAD"==n?d:f[p[n]];for(h.debug(r,e);e>0;)if(r=f[r.parent],e--,!r){var i="Critical error - unique parent commit not found during reset";throw h.error(i),i}d=r,p[g]=r.id},e.prettyPrint=function(){h.debug(f);var t=e.getCommitsArray()[0];s([t])},e.clear=function(){f={},d=null,p={master:d},g="master",m=0},e.getBranchesAsObjArray=function(){var t=l.map(p,function(t,n){return{name:n,commit:f[t]}});return t},e.getBranches=function(){return p},e.getCommits=function(){return f},e.getCommitsArray=function(){var t=Object.keys(f).map(function(t){return f[t]});return l.each(t,function(t){h.debug(t.id)}),l.orderBy(t,["seq"],["desc"])},e.getCurrentBranch=function(){return g},e.getDirection=function(){return y},e.getHead=function(){return d}},{"../../logger":130,lodash:103}],124:[function(t,n,e){"use strict";function r(t){t.append("defs").append("g").attr("id","def-commit").append("circle").attr("r",v.nodeRadius).attr("cx",0).attr("cy",0),t.select("#def-commit").append("foreignObject").attr("width",v.nodeLabel.width).attr("height",v.nodeLabel.height).attr("x",v.nodeLabel.x).attr("y",v.nodeLabel.y).attr("class","node-label").attr("requiredFeatures","http://www.w3.org/TR/SVG11/feature#Extensibility").append("xhtml:p").html("")}function i(t,n,e,r){r=r||"basis";var i=v.branchColors[e%v.branchColors.length],a=p.svg.line().x(function(t){return Math.round(t.x)}).y(function(t){return Math.round(t.y)}).interpolate(r);t.append("svg:path").attr("d",a(n)).style("stroke",i).style("stroke-width",v.lineStrokeWidth).style("fill","none")}function a(t,n){n=n||t.node().getBBox();var e=t.node().getCTM(),r=e.e+n.x*e.a,i=e.f+n.y*e.d; - -return{left:r,top:i,width:n.width,height:n.height}}function u(t,n,e,r,u){y.debug("svgDrawLineForCommits: ",n,e);var o=a(t.select("#node-"+n+" circle")),s=a(t.select("#node-"+e+" circle"));switch(r){case"LR":if(o.left-s.left>v.nodeSpacing){var c={x:o.left-v.nodeSpacing,y:s.top+s.height/2},l={x:s.left+s.width,y:s.top+s.height/2};i(t,[c,l],u,"linear"),i(t,[{x:o.left,y:o.top+o.height/2},{x:o.left-v.nodeSpacing/2,y:o.top+o.height/2},{x:o.left-v.nodeSpacing/2,y:c.y},c],u)}else i(t,[{x:o.left,y:o.top+o.height/2},{x:o.left-v.nodeSpacing/2,y:o.top+o.height/2},{x:o.left-v.nodeSpacing/2,y:s.top+s.height/2},{x:s.left+s.width,y:s.top+s.height/2}],u);break;case"BT":s.top-o.top>v.nodeSpacing?(c={x:s.left+s.width/2,y:o.top+o.height+v.nodeSpacing},l={x:s.left+s.width/2,y:s.top},i(t,[c,l],u,"linear"),i(t,[{x:o.left+o.width/2,y:o.top+o.height},{x:o.left+o.width/2,y:o.top+o.height+v.nodeSpacing/2},{x:s.left+s.width/2,y:c.y-v.nodeSpacing/2},c],u)):i(t,[{x:o.left+o.width/2,y:o.top+o.height},{x:o.left+o.width/2,y:o.top+v.nodeSpacing/2},{x:s.left+s.width/2,y:s.top-v.nodeSpacing/2},{x:s.left+s.width/2,y:s.top}],u)}}function o(t,n){return t.select(n).node().cloneNode(!0)}function s(t,n,e,r){var i,a=Object.keys(m).length;if(f.isString(n))do{if(i=m[n],y.debug("in renderCommitHistory",i.id,i.seq),t.select("#node-"+n).size()>0)return;t.append(function(){return o(t,"#def-commit")}).attr("class","commit").attr("id",function(){return"node-"+i.id}).attr("transform",function(){switch(r){case"LR":return"translate("+(i.seq*v.nodeSpacing+v.leftMargin)+", "+l*v.branchOffset+")";case"BT":return"translate("+(l*v.branchOffset+v.leftMargin)+", "+(a-i.seq)*v.nodeSpacing+")"}}).attr("fill",v.nodeFillColor).attr("stroke",v.nodeStrokeColor).attr("stroke-width",v.nodeStrokeWidth);var u=f.find(e,["commit",i]);u&&(y.debug("found branch ",u.name),t.select("#node-"+i.id+" p").append("xhtml:span").attr("class","branch-label").text(u.name+", ")),t.select("#node-"+i.id+" p").append("xhtml:span").attr("class","commit-id").text(i.id),""!==i.message&&"BT"===r&&t.select("#node-"+i.id+" p").append("xhtml:span").attr("class","commit-msg").text(", "+i.message),n=i.parent}while(n&&m[n]);f.isArray(n)&&(y.debug("found merge commmit",n),s(t,n[0],e,r),l++,s(t,n[1],e,r),l--)}function c(t,n,e,r){for(r=r||0;n.seq>0&&!n.lineDrawn;)f.isString(n.parent)?(u(t,n.id,n.parent,e,r),n.lineDrawn=!0,n=m[n.parent]):f.isArray(n.parent)&&(u(t,n.id,n.parent[0],e,r),u(t,n.id,n.parent[1],e,r+1),c(t,m[n.parent[1]],e,r+1),n.lineDrawn=!0,n=m[n.parent[0]])}var l,h=t("./gitGraphAst"),f=t("lodash"),d=t("./parser/gitGraph"),p=t("../../d3"),g=t("../../logger"),y=new g.Log,m={},v={nodeSpacing:75,nodeFillColor:"yellow",nodeStrokeWidth:2,nodeStrokeColor:"grey",lineStrokeWidth:4,branchOffset:50,lineColor:"grey",leftMargin:50,branchColors:["#442f74","#983351","#609732","#AA9A39"],nodeRadius:15,nodeLabel:{width:75,height:100,x:-25,y:15}},_={};e.setConf=function(t){_=t},e.draw=function(t,n,e){try{var i;i=d.parser,i.yy=h,y.debug("in gitgraph renderer",t,n,e),i.parse(t+"\n"),v=f.extend(v,_,h.getOptions()),y.debug("effective options",v);var a=h.getDirection();m=h.getCommits();var u=h.getBranchesAsObjArray();"BT"===a&&(v.nodeLabel.x=u.length*v.branchOffset,v.nodeLabel.width="100%",v.nodeLabel.y=-2*v.nodeRadius);var o=p.select("#"+n);r(o),l=1,f.each(u,function(t){s(o,t.commit.id,u,a),c(o,t.commit,a),l++}),o.attr("height",function(){return"BT"===a?Object.keys(m).length*v.nodeSpacing:(u.length+1)*v.branchOffset})}catch(g){y.error("Error while rendering gitgraph"),y.error(g.message)}}},{"../../d3":108,"../../logger":130,"./gitGraphAst":123,"./parser/gitGraph":125,lodash:103}],125:[function(t,n,e){(function(r){"use strict";var i=function(){function t(){this.yy={}}var n=function(t,n,e,r){for(e=e||{},r=t.length;r--;e[t[r]]=n);return e},e=[2,3],r=[1,7],i=[7,12,15,17,19,20,21],a=[7,11,12,15,17,19,20,21],u=[2,20],o=[1,32],s={trace:function(){},yy:{},symbols_:{error:2,start:3,GG:4,":":5,document:6,EOF:7,DIR:8,options:9,body:10,OPT:11,NL:12,line:13,statement:14,COMMIT:15,commit_arg:16,BRANCH:17,ID:18,CHECKOUT:19,MERGE:20,RESET:21,reset_arg:22,STR:23,HEAD:24,reset_parents:25,CARET:26,$accept:0,$end:1},terminals_:{2:"error",4:"GG",5:":",7:"EOF",8:"DIR",11:"OPT",12:"NL",15:"COMMIT",17:"BRANCH",18:"ID",19:"CHECKOUT",20:"MERGE",21:"RESET",23:"STR",24:"HEAD",26:"CARET"},productions_:[0,[3,4],[3,5],[6,0],[6,2],[9,2],[9,1],[10,0],[10,2],[13,2],[13,1],[14,2],[14,2],[14,2],[14,2],[14,2],[16,0],[16,1],[22,2],[22,2],[25,0],[25,2]],performAction:function(t,n,e,r,i,a){var u=a.length-1;switch(i){case 1:return a[u-1];case 2:return r.setDirection(a[u-3]),a[u-1];case 4:r.setOptions(a[u-1]),this.$=a[u];break;case 5:a[u-1]+=a[u],this.$=a[u-1];break;case 7:this.$=[];break;case 8:a[u-1].push(a[u]),this.$=a[u-1];break;case 9:this.$=a[u-1];break;case 11:r.commit(a[u]);break;case 12:r.branch(a[u]);break;case 13:r.checkout(a[u]);break;case 14:r.merge(a[u]);break;case 15:r.reset(a[u]);break;case 16:this.$="";break;case 17:this.$=a[u];break;case 18:this.$=a[u-1]+":"+a[u];break;case 19:this.$=a[u-1]+":"+r.count,r.count=0;break;case 20:r.count=0;break;case 21:r.count+=1}},table:[{3:1,4:[1,2]},{1:[3]},{5:[1,3],8:[1,4]},{6:5,7:e,9:6,12:r},{5:[1,8]},{7:[1,9]},n(i,[2,7],{10:10,11:[1,11]}),n(a,[2,6]),{6:12,7:e,9:6,12:r},{1:[2,1]},{7:[2,4],12:[1,15],13:13,14:14,15:[1,16],17:[1,17],19:[1,18],20:[1,19],21:[1,20]},n(a,[2,5]),{7:[1,21]},n(i,[2,8]),{12:[1,22]},n(i,[2,10]),{12:[2,16],16:23,23:[1,24]},{18:[1,25]},{18:[1,26]},{18:[1,27]},{18:[1,30],22:28,24:[1,29]},{1:[2,2]},n(i,[2,9]),{12:[2,11]},{12:[2,17]},{12:[2,12]},{12:[2,13]},{12:[2,14]},{12:[2,15]},{12:u,25:31,26:o},{12:u,25:33,26:o},{12:[2,18]},{12:u,25:34,26:o},{12:[2,19]},{12:[2,21]}],defaultActions:{9:[2,1],21:[2,2],23:[2,11],24:[2,17],25:[2,12],26:[2,13],27:[2,14],28:[2,15],31:[2,18],33:[2,19],34:[2,21]},parseError:function(t,n){if(!n.recoverable){var e=function(t,n){this.message=t,this.hash=n};throw e.prototype=Error,new e(t,n)}this.trace(t)},parse:function(t){var n=this,e=[0],r=[null],i=[],a=this.table,u="",o=0,s=0,c=0,l=2,h=1,f=i.slice.call(arguments,1),d=Object.create(this.lexer),p={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(p.yy[g]=this.yy[g]);d.setInput(t,p.yy),p.yy.lexer=d,p.yy.parser=this,"undefined"==typeof d.yylloc&&(d.yylloc={});var y=d.yylloc;i.push(y);var m=d.options&&d.options.ranges;this.parseError="function"==typeof p.yy.parseError?p.yy.parseError:Object.getPrototypeOf(this).parseError;for(var v,_,b,x,w,A,k,E,M,S=function(){var t;return t=d.lex()||h,"number"!=typeof t&&(t=n.symbols_[t]||t),t},D={};;){if(b=e[e.length-1],this.defaultActions[b]?x=this.defaultActions[b]:((null===v||"undefined"==typeof v)&&(v=S()),x=a[b]&&a[b][v]),"undefined"==typeof x||!x.length||!x[0]){var C="";M=[];for(A in a[b])this.terminals_[A]&&A>l&&M.push("'"+this.terminals_[A]+"'");C=d.showPosition?"Parse error on line "+(o+1)+":\n"+d.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[v]||v)+"'":"Parse error on line "+(o+1)+": Unexpected "+(v==h?"end of input":"'"+(this.terminals_[v]||v)+"'"),this.parseError(C,{text:d.match,token:this.terminals_[v]||v,line:d.yylineno,loc:y,expected:M})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+v);switch(x[0]){case 1:e.push(v),r.push(d.yytext),i.push(d.yylloc),e.push(x[1]),v=null,_?(v=_,_=null):(s=d.yyleng,u=d.yytext,o=d.yylineno,y=d.yylloc,c>0&&c--);break;case 2:if(k=this.productions_[x[1]][1],D.$=r[r.length-k],D._$={first_line:i[i.length-(k||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(k||1)].first_column,last_column:i[i.length-1].last_column},m&&(D._$.range=[i[i.length-(k||1)].range[0],i[i.length-1].range[1]]),w=this.performAction.apply(D,[u,s,o,p.yy,x[1],r,i].concat(f)),"undefined"!=typeof w)return w;k&&(e=e.slice(0,-1*k*2),r=r.slice(0,-1*k),i=i.slice(0,-1*k)),e.push(this.productions_[x[1]][0]),r.push(D.$),i.push(D._$),E=a[e[e.length-2]][e[e.length-1]],e.push(E);break;case 3:return!0}}return!0}},c=function(){var t={EOF:1,parseError:function(t,n){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,n)},setInput:function(t,n){return this.yy=n||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t;var n=t.match(/(?:\r\n?|\n).*/g);return n?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var n=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===r.length?this.yylloc.first_column:0)+r[r.length-e.length].length-e[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),n=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+n+"^"},test_match:function(t,n){var e,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),r=t[0].match(/(?:\r\n?|\n).*/g),r&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,n,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var t,n,e,r;this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;an[0].length)){if(n=e,r=a,this.options.backtrack_lexer){if(t=this.test_match(e,i[a]),t!==!1)return t;if(this._backtrack){n=!1;continue}return!1}if(!this.options.flex)break}return n?(t=this.test_match(n,i[r]),t!==!1?t:!1):""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t?t:this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){var t=this.conditionStack.length-1;return t>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return t=this.conditionStack.length-1-Math.abs(t||0),t>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,n,e,r){switch(e){case 0:return 12;case 1:break;case 2:break;case 3:break;case 4:return 4;case 5:return 15;case 6:return 17;case 7:return 20;case 8:return 21;case 9:return 19;case 10:return 8;case 11:return 8;case 12:return 5;case 13:return 26;case 14:this.begin("options");break;case 15:this.popState();break;case 16:return 11;case 17:this.begin("string");break;case 18:this.popState();break;case 19:return 23;case 20:return 18;case 21:return 7}},rules:[/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gitGraph\b)/i,/^(?:commit\b)/i,/^(?:branch\b)/i,/^(?:merge\b)/i,/^(?:reset\b)/i,/^(?:checkout\b)/i,/^(?:LR\b)/i,/^(?:BT\b)/i,/^(?::)/i,/^(?:\^)/i,/^(?:options\r?\n)/i,/^(?:end\r?\n)/i,/^(?:[^\n]+\r?\n)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[a-zA-Z][a-zA-Z0-9_]+)/i,/^(?:$)/i],conditions:{options:{rules:[15,16],inclusive:!1},string:{rules:[18,19],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,20,21],inclusive:!0}}};return t}();return s.lexer=c,t.prototype=s,s.Parser=t,new t}();"undefined"!=typeof t&&"undefined"!=typeof e&&(e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(n){n[1]||(console.log("Usage: "+n[0]+" FILE"),r.exit(1));var i=t("fs").readFileSync(t("path").normalize(n[1]),"utf8");return e.parser.parse(i)},"undefined"!=typeof n&&t.main===n&&e.main(r.argv.slice(1)))}).call(this,t("_process"))},{_process:106,fs:1,path:105}],126:[function(t,n,e){(function(r){"use strict";var i=function(){function t(){this.yy={}}var n=function(t,n,e,r){for(e=e||{},r=t.length;r--;e[t[r]]=n);return e},e=[1,2],r=[1,3],i=[1,4],a=[2,4],u=[1,9],o=[1,11],s=[1,12],c=[1,14],l=[1,15],h=[1,17],f=[1,18],d=[1,19],p=[1,20],g=[1,22],y=[1,23],m=[1,4,5,10,15,16,18,20,21,22,23,24,25,36],v=[1,31],_=[4,5,10,15,16,18,20,21,22,23,25,36],b=[34,35,36],x={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,SD:6,document:7,line:8,statement:9,participant:10,actor:11,AS:12,restOfLine:13,signal:14,activate:15,deactivate:16,note_statement:17,title:18,text2:19,loop:20,end:21,opt:22,alt:23,"else":24,note:25,placement:26,over:27,actor_pair:28,spaceList:29,",":30,left_of:31,right_of:32,signaltype:33,"+":34,"-":35,ACTOR:36,SOLID_OPEN_ARROW:37,DOTTED_OPEN_ARROW:38,SOLID_ARROW:39,DOTTED_ARROW:40,SOLID_CROSS:41,DOTTED_CROSS:42,TXT:43,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",6:"SD",10:"participant",12:"AS",13:"restOfLine",15:"activate",16:"deactivate",18:"title",20:"loop",21:"end",22:"opt",23:"alt",24:"else",25:"note",27:"over",30:",",31:"left_of",32:"right_of",34:"+",35:"-",36:"ACTOR",37:"SOLID_OPEN_ARROW",38:"DOTTED_OPEN_ARROW",39:"SOLID_ARROW",40:"DOTTED_ARROW",41:"SOLID_CROSS",42:"DOTTED_CROSS",43:"TXT"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,5],[9,3],[9,2],[9,3],[9,3],[9,2],[9,3],[9,4],[9,4],[9,7],[17,4],[17,4],[29,2],[29,1],[28,3],[28,1],[26,1],[26,1],[14,5],[14,5],[14,4],[11,1],[33,1],[33,1],[33,1],[33,1],[33,1],[33,1],[19,1]],performAction:function(t,n,e,r,i,a){var u=a.length-1;switch(i){case 3:return r.apply(a[u]),a[u];case 4:this.$=[];break;case 5:a[u-1].push(a[u]),this.$=a[u-1];break;case 6:case 7:this.$=a[u];break;case 8:this.$=[];break;case 9:a[u-3].description=a[u-1],this.$=a[u-3];break;case 10:this.$=a[u-1];break;case 12:this.$={type:"activeStart",signalType:r.LINETYPE.ACTIVE_START,actor:a[u-1]};break;case 13:this.$={type:"activeEnd",signalType:r.LINETYPE.ACTIVE_END,actor:a[u-1]};break;case 15:this.$=[{type:"setTitle",text:a[u-1]}];break;case 16:a[u-1].unshift({type:"loopStart",loopText:a[u-2],signalType:r.LINETYPE.LOOP_START}),a[u-1].push({type:"loopEnd",loopText:a[u-2],signalType:r.LINETYPE.LOOP_END}),this.$=a[u-1];break;case 17:a[u-1].unshift({type:"optStart",optText:a[u-2],signalType:r.LINETYPE.OPT_START}),a[u-1].push({type:"optEnd",optText:a[u-2],signalType:r.LINETYPE.OPT_END}),this.$=a[u-1];break;case 18:a[u-4].unshift({type:"altStart",altText:a[u-5],signalType:r.LINETYPE.ALT_START}),a[u-4].push({type:"else",altText:a[u-2],signalType:r.LINETYPE.ALT_ELSE}),a[u-4]=a[u-4].concat(a[u-1]),a[u-4].push({type:"altEnd",signalType:r.LINETYPE.ALT_END}),this.$=a[u-4];break;case 19:this.$=[a[u-1],{type:"addNote",placement:a[u-2],actor:a[u-1].actor,text:a[u]}];break;case 20:a[u-2]=[].concat(a[u-1],a[u-1]).slice(0,2),a[u-2][0]=a[u-2][0].actor,a[u-2][1]=a[u-2][1].actor,this.$=[a[u-1],{type:"addNote",placement:r.PLACEMENT.OVER,actor:a[u-2].slice(0,2),text:a[u]}];break;case 23:this.$=[a[u-2],a[u]];break;case 24:this.$=a[u];break;case 25:this.$=r.PLACEMENT.LEFTOF;break;case 26:this.$=r.PLACEMENT.RIGHTOF;break;case 27:this.$=[a[u-4],a[u-1],{type:"addMessage",from:a[u-4].actor,to:a[u-1].actor,signalType:a[u-3],msg:a[u]},{type:"activeStart",signalType:r.LINETYPE.ACTIVE_START,actor:a[u-1]}];break;case 28:this.$=[a[u-4],a[u-1],{type:"addMessage",from:a[u-4].actor,to:a[u-1].actor,signalType:a[u-3],msg:a[u]},{type:"activeEnd",signalType:r.LINETYPE.ACTIVE_END,actor:a[u-4]}];break;case 29:this.$=[a[u-3],a[u-1],{type:"addMessage",from:a[u-3].actor,to:a[u-1].actor,signalType:a[u-2],msg:a[u]}];break;case 30:this.$={type:"addActor",actor:a[u]};break;case 31:this.$=r.LINETYPE.SOLID_OPEN;break;case 32:this.$=r.LINETYPE.DOTTED_OPEN;break;case 33:this.$=r.LINETYPE.SOLID;break;case 34:this.$=r.LINETYPE.DOTTED;break;case 35:this.$=r.LINETYPE.SOLID_CROSS;break;case 36:this.$=r.LINETYPE.DOTTED_CROSS;break;case 37:this.$=a[u].substring(1).trim().replace(/\\n/gm,"\n")}},table:[{3:1,4:e,5:r,6:i},{1:[3]},{3:5,4:e,5:r,6:i},{3:6,4:e,5:r,6:i},n([1,4,5,10,15,16,18,20,22,23,25,36],a,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:u,5:o,8:8,9:10,10:s,11:21,14:13,15:c,16:l,17:16,18:h,20:f,22:d,23:p,25:g,36:y},n(m,[2,5]),{9:24,10:s,11:21,14:13,15:c,16:l,17:16,18:h,20:f,22:d,23:p,25:g,36:y},n(m,[2,7]),n(m,[2,8]),{11:25,36:y},{5:[1,26]},{11:27,36:y},{11:28,36:y},{5:[1,29]},{19:30,43:v},{13:[1,32]},{13:[1,33]},{13:[1,34]},{33:35,37:[1,36],38:[1,37],39:[1,38],40:[1,39],41:[1,40],42:[1,41]},{26:42,27:[1,43],31:[1,44],32:[1,45]},n([5,12,30,37,38,39,40,41,42,43],[2,30]),n(m,[2,6]),{5:[1,47],12:[1,46]},n(m,[2,11]),{5:[1,48]},{5:[1,49]},n(m,[2,14]),{5:[1,50]},{5:[2,37]},n(_,a,{7:51}),n(_,a,{7:52}),n([4,5,10,15,16,18,20,22,23,24,25,36],a,{7:53}),{11:56,34:[1,54],35:[1,55],36:y},n(b,[2,31]),n(b,[2,32]),n(b,[2,33]),n(b,[2,34]),n(b,[2,35]),n(b,[2,36]),{11:57,36:y},{11:59,28:58,36:y},{36:[2,25]},{36:[2,26]},{13:[1,60]},n(m,[2,10]),n(m,[2,12]),n(m,[2,13]),n(m,[2,15]),{4:u,5:o,8:8,9:10,10:s,11:21,14:13,15:c,16:l,17:16,18:h,20:f,21:[1,61],22:d,23:p,25:g,36:y},{4:u,5:o,8:8,9:10,10:s,11:21,14:13,15:c,16:l,17:16,18:h,20:f,21:[1,62],22:d,23:p,25:g,36:y},{4:u,5:o,8:8,9:10,10:s,11:21,14:13,15:c,16:l,17:16,18:h,20:f,22:d,23:p,24:[1,63],25:g,36:y},{11:64,36:y},{11:65,36:y},{19:66,43:v},{19:67,43:v},{19:68,43:v},{30:[1,69],43:[2,24]},{5:[1,70]},n(m,[2,16]),n(m,[2,17]),{13:[1,71]},{19:72,43:v},{19:73,43:v},{5:[2,29]},{5:[2,19]},{5:[2,20]},{11:74,36:y},n(m,[2,9]),n(_,a,{7:75}),{5:[2,27]},{5:[2,28]},{43:[2,23]},{4:u,5:o,8:8,9:10,10:s,11:21,14:13,15:c,16:l,17:16,18:h,20:f,21:[1,76],22:d,23:p,25:g,36:y},n(m,[2,18])],defaultActions:{5:[2,1],6:[2,2],31:[2,37],44:[2,25],45:[2,26],66:[2,29],67:[2,19],68:[2,20],72:[2,27],73:[2,28],74:[2,23]},parseError:function(t,n){if(!n.recoverable){var e=function(t,n){this.message=t,this.hash=n};throw e.prototype=Error,new e(t,n)}this.trace(t)},parse:function(t){var n=this,e=[0],r=[null],i=[],a=this.table,u="",o=0,s=0,c=0,l=2,h=1,f=i.slice.call(arguments,1),d=Object.create(this.lexer),p={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(p.yy[g]=this.yy[g]);d.setInput(t,p.yy),p.yy.lexer=d,p.yy.parser=this,"undefined"==typeof d.yylloc&&(d.yylloc={});var y=d.yylloc;i.push(y);var m=d.options&&d.options.ranges;this.parseError="function"==typeof p.yy.parseError?p.yy.parseError:Object.getPrototypeOf(this).parseError;for(var v,_,b,x,w,A,k,E,M,S=function(){var t;return t=d.lex()||h,"number"!=typeof t&&(t=n.symbols_[t]||t),t},D={};;){if(b=e[e.length-1],this.defaultActions[b]?x=this.defaultActions[b]:((null===v||"undefined"==typeof v)&&(v=S()),x=a[b]&&a[b][v]),"undefined"==typeof x||!x.length||!x[0]){var C="";M=[];for(A in a[b])this.terminals_[A]&&A>l&&M.push("'"+this.terminals_[A]+"'");C=d.showPosition?"Parse error on line "+(o+1)+":\n"+d.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[v]||v)+"'":"Parse error on line "+(o+1)+": Unexpected "+(v==h?"end of input":"'"+(this.terminals_[v]||v)+"'"),this.parseError(C,{text:d.match,token:this.terminals_[v]||v,line:d.yylineno,loc:y,expected:M})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+v);switch(x[0]){case 1:e.push(v),r.push(d.yytext),i.push(d.yylloc),e.push(x[1]),v=null,_?(v=_,_=null):(s=d.yyleng,u=d.yytext,o=d.yylineno,y=d.yylloc,c>0&&c--);break;case 2:if(k=this.productions_[x[1]][1],D.$=r[r.length-k],D._$={first_line:i[i.length-(k||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(k||1)].first_column,last_column:i[i.length-1].last_column},m&&(D._$.range=[i[i.length-(k||1)].range[0],i[i.length-1].range[1]]),w=this.performAction.apply(D,[u,s,o,p.yy,x[1],r,i].concat(f)),"undefined"!=typeof w)return w;k&&(e=e.slice(0,-1*k*2),r=r.slice(0,-1*k),i=i.slice(0,-1*k)),e.push(this.productions_[x[1]][0]),r.push(D.$),i.push(D._$),E=a[e[e.length-2]][e[e.length-1]],e.push(E);break;case 3:return!0}}return!0}},w=function(){var t={EOF:1,parseError:function(t,n){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,n)},setInput:function(t,n){return this.yy=n||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t;var n=t.match(/(?:\r\n?|\n).*/g);return n?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var n=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===r.length?this.yylloc.first_column:0)+r[r.length-e.length].length-e[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),n=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+n+"^"},test_match:function(t,n){var e,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),r=t[0].match(/(?:\r\n?|\n).*/g),r&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,n,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var t,n,e,r;this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;an[0].length)){if(n=e,r=a,this.options.backtrack_lexer){if(t=this.test_match(e,i[a]),t!==!1)return t;if(this._backtrack){n=!1;continue}return!1}if(!this.options.flex)break}return n?(t=this.test_match(n,i[r]),t!==!1?t:!1):""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t?t:this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){var t=this.conditionStack.length-1;return t>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return t=this.conditionStack.length-1-Math.abs(t||0),t>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,n,e,r){switch(e){case 0:return 5;case 1:break;case 2:break;case 3:break;case 4:break;case 5:return this.begin("ID"),10;case 6:return this.begin("ALIAS"),36;case 7:return this.popState(),this.popState(),this.begin("LINE"),12;case 8:return this.popState(),this.popState(),5;case 9:return this.begin("LINE"),20;case 10:return this.begin("LINE"),22;case 11:return this.begin("LINE"),23;case 12:return this.begin("LINE"),24;case 13:return this.popState(),13;case 14:return 21;case 15:return 31;case 16:return 32;case 17:return 27;case 18:return 25;case 19:return this.begin("ID"),15;case 20:return this.begin("ID"),16;case 21:return 18;case 22:return 6;case 23:return 30;case 24:return 5;case 25:return n.yytext=n.yytext.trim(),36;case 26:return 39;case 27:return 40;case 28:return 37;case 29:return 38;case 30:return 41;case 31:return 42;case 32:return 43;case 33:return 34;case 34:return 35;case 35:return 5;case 36:return"INVALID"}},rules:[/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:participant\b)/i,/^(?:[^\->:\n,;]+?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\b)/i,/^(?:sequenceDiagram\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\->:\n,;]+)/i,/^(?:->>)/i,/^(?:-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?::[^#\n;]+)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],conditions:{LINE:{rules:[2,3,13],inclusive:!1},ALIAS:{rules:[2,3,7,8],inclusive:!1},ID:{rules:[2,3,6],inclusive:!1},INITIAL:{rules:[0,1,3,4,5,9,10,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],inclusive:!0}}};return t}();return x.lexer=w,t.prototype=x,x.Parser=t,new t}();"undefined"!=typeof t&&"undefined"!=typeof e&&(e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(n){n[1]||(console.log("Usage: "+n[0]+" FILE"),r.exit(1));var i=t("fs").readFileSync(t("path").normalize(n[1]),"utf8");return e.parser.parse(i)},"undefined"!=typeof n&&t.main===n&&e.main(r.argv.slice(1)))}).call(this,t("_process"))},{_process:106,fs:1,path:105}],127:[function(t,n,e){(function(n){"use strict";var r={},i=[],a=[],u="",o=t("../../logger"),s=new o.Log;e.addActor=function(t,n,e){var i=r[t];i&&n===i.name&&null==e||(null==e&&(e=n),r[t]={name:n,description:e})},e.addMessage=function(t,n,e,r){i.push({from:t,to:n,message:e,answer:r})},e.addSignal=function(t,n,e,r){s.debug("Adding message from="+t+" to="+n+" message="+e+" type="+r),i.push({from:t,to:n,message:e,type:r})},e.getMessages=function(){return i},e.getActors=function(){return r},e.getActor=function(t){return r[t]},e.getActorKeys=function(){return Object.keys(r)},e.getTitle=function(){return u},e.clear=function(){r={},i=[]},e.LINETYPE={SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18},e.ARROWTYPE={FILLED:0,OPEN:1},e.PLACEMENT={LEFTOF:0,RIGHTOF:1,OVER:2},e.addNote=function(t,n,r){var u={actor:t,placement:n,message:r},o=[].concat(t,t);a.push(u),i.push({from:o[0],to:o[1],message:r,type:e.LINETYPE.NOTE,placement:n})},e.setTitle=function(t){u=t},e.parseError=function(t,e){n.mermaidAPI.parseError(t,e)},e.apply=function(t){if(t instanceof Array)t.forEach(function(t){e.apply(t)});else switch(t.type){case"addActor":e.addActor(t.actor,t.actor,t.description);break;case"activeStart":e.addSignal(t.actor,void 0,void 0,t.signalType);break;case"activeEnd":e.addSignal(t.actor,void 0,void 0,t.signalType);break;case"addNote":e.addNote(t.actor,t.placement,t.text);break;case"addMessage":e.addSignal(t.from,t.to,t.msg,t.signalType);break;case"loopStart":e.addSignal(void 0,void 0,t.loopText,t.signalType);break;case"loopEnd":e.addSignal(void 0,void 0,void 0,t.signalType);break;case"optStart":e.addSignal(void 0,void 0,t.optText,t.signalType);break;case"optEnd":e.addSignal(void 0,void 0,void 0,t.signalType);break;case"altStart":e.addSignal(void 0,void 0,t.altText,t.signalType);break;case"else":e.addSignal(void 0,void 0,t.altText,t.signalType);break;case"altEnd":e.addSignal(void 0,void 0,void 0,t.signalType);break;case"setTitle":e.setTitle(t.text)}}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../../logger":130}],128:[function(t,n,e){"use strict";var r=t("./parser/sequenceDiagram").parser;r.yy=t("./sequenceDb");var i=t("./svgDraw"),a=t("../../d3"),u=t("../../logger"),o=new u.Log,s={ -diagramMarginX:50,diagramMarginY:30,actorMargin:50,width:150,height:65,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,mirrorActors:!1,bottomMarginAdj:1,activationWidth:10,textPlacement:"tspan"};e.bounds={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],activations:[],init:function(){this.sequenceItems=[],this.activations=[],this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0},updateVal:function(t,n,e,r){t[n]="undefined"==typeof t[n]?e:r(e,t[n])},updateBounds:function(t,n,r,i){function a(a){return function(c){o++;var l=u.sequenceItems.length-o+1;u.updateVal(c,"starty",n-l*s.boxMargin,Math.min),u.updateVal(c,"stopy",i+l*s.boxMargin,Math.max),u.updateVal(e.bounds.data,"startx",t-l*s.boxMargin,Math.min),u.updateVal(e.bounds.data,"stopx",r+l*s.boxMargin,Math.max),"activation"!=a&&(u.updateVal(c,"startx",t-l*s.boxMargin,Math.min),u.updateVal(c,"stopx",r+l*s.boxMargin,Math.max),u.updateVal(e.bounds.data,"starty",n-l*s.boxMargin,Math.min),u.updateVal(e.bounds.data,"stopy",i+l*s.boxMargin,Math.max))}}var u=this,o=0;this.sequenceItems.forEach(a()),this.activations.forEach(a("activation"))},insert:function(t,n,r,i){var a,u,o,s;a=Math.min(t,r),o=Math.max(t,r),u=Math.min(n,i),s=Math.max(n,i),this.updateVal(e.bounds.data,"startx",a,Math.min),this.updateVal(e.bounds.data,"starty",u,Math.min),this.updateVal(e.bounds.data,"stopx",o,Math.max),this.updateVal(e.bounds.data,"stopy",s,Math.max),this.updateBounds(a,u,o,s)},newActivation:function(t,n){var e=r.yy.getActors()[t.from.actor],a=h(t.from.actor).length,u=e.x+s.width/2+(a-1)*s.activationWidth/2;this.activations.push({startx:u,starty:this.verticalPos+2,stopx:u+s.activationWidth,stopy:void 0,actor:t.from.actor,anchored:i.anchorElement(n)})},endActivation:function(t){var n=this.activations.map(function(t){return t.actor}).lastIndexOf(t.from.actor),e=this.activations.splice(n,1)[0];return e},newLoop:function(t){this.sequenceItems.push({startx:void 0,starty:this.verticalPos,stopx:void 0,stopy:void 0,title:t})},endLoop:function(){var t=this.sequenceItems.pop();return t},addElseToLoop:function(t){var n=this.sequenceItems.pop();n.elsey=e.bounds.getVerticalPos(),n.elseText=t,this.sequenceItems.push(n)},bumpVerticalPos:function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=this.verticalPos},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return this.data}};var c=function(t,n,r,a,u){var o=i.getNoteRect();o.x=n,o.y=r,o.width=u||s.width,o["class"]="note";var c=t.append("g"),l=i.drawRect(c,o),h=i.getTextObj();h.x=n-4,h.y=r-13,h.textMargin=s.noteMargin,h.dy="1em",h.text=a.message,h["class"]="noteText";var f=i.drawText(c,h,o.width-s.noteMargin),d=f[0][0].getBBox().height;!u&&d>s.width?(f.remove(),c=t.append("g"),f=i.drawText(c,h,2*o.width-s.noteMargin),d=f[0][0].getBBox().height,l.attr("width",2*o.width),e.bounds.insert(n,r,n+2*o.width,r+2*s.noteMargin+d)):e.bounds.insert(n,r,n+o.width,r+2*s.noteMargin+d),l.attr("height",d+2*s.noteMargin),e.bounds.bumpVerticalPos(d+2*s.noteMargin)},l=function(t,n,i,a,u){var o,c=t.append("g"),l=n+(i-n)/2,h=c.append("text").attr("x",l).attr("y",a-7).style("text-anchor","middle").attr("class","messageText").text(u.message);o="undefined"!=typeof h[0][0].getBBox?h[0][0].getBBox().width:h[0][0].getBoundingClientRect();var f;if(n===i){f=c.append("path").attr("d","M "+n+","+a+" C "+(n+60)+","+(a-10)+" "+(n+60)+","+(a+30)+" "+n+","+(a+20)),e.bounds.bumpVerticalPos(30);var d=Math.max(o/2,100);e.bounds.insert(n-d,e.bounds.getVerticalPos()-10,i+d,e.bounds.getVerticalPos())}else f=c.append("line"),f.attr("x1",n),f.attr("y1",a),f.attr("x2",i),f.attr("y2",a),e.bounds.insert(n,e.bounds.getVerticalPos()-10,i,e.bounds.getVerticalPos());u.type===r.yy.LINETYPE.DOTTED||u.type===r.yy.LINETYPE.DOTTED_CROSS||u.type===r.yy.LINETYPE.DOTTED_OPEN?(f.style("stroke-dasharray","3, 3"),f.attr("class","messageLine1")):f.attr("class","messageLine0");var p="";s.arrowMarkerAbsolute&&(p=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,p=p.replace(/\(/g,"\\("),p=p.replace(/\)/g,"\\)")),f.attr("stroke-width",2),f.attr("stroke","black"),f.style("fill","none"),(u.type===r.yy.LINETYPE.SOLID||u.type===r.yy.LINETYPE.DOTTED)&&f.attr("marker-end","url("+p+"#arrowhead)"),(u.type===r.yy.LINETYPE.SOLID_CROSS||u.type===r.yy.LINETYPE.DOTTED_CROSS)&&f.attr("marker-end","url("+p+"#crosshead)")};n.exports.drawActors=function(t,n,r,a){var u;for(u=0;un&&(r.starty=n-6,n+=12),i.drawActivation(y,r,n,s),e.bounds.insert(r.startx,n-10,r.stopx,n)}r.yy.clear(),r.parse(t+"\n"),e.bounds.init();var d,p,g,y=a.select("#"+u),m=r.yy.getActors(),v=r.yy.getActorKeys(),_=r.yy.getMessages(),b=r.yy.getTitle();n.exports.drawActors(y,m,v,0),i.insertArrowHead(y),i.insertArrowCrossHead(y);var x;_.forEach(function(t){var n;switch(t.type){case r.yy.LINETYPE.NOTE:e.bounds.bumpVerticalPos(s.boxMargin),d=m[t.from].x,p=m[t.to].x,t.placement===r.yy.PLACEMENT.RIGHTOF?c(y,d+(s.width+s.actorMargin)/2,e.bounds.getVerticalPos(),t):t.placement===r.yy.PLACEMENT.LEFTOF?c(y,d-(s.width+s.actorMargin)/2,e.bounds.getVerticalPos(),t):t.to===t.from?c(y,d,e.bounds.getVerticalPos(),t):(g=Math.abs(d-p)+s.actorMargin,c(y,(d+p+s.width-g)/2,e.bounds.getVerticalPos(),t,g));break;case r.yy.LINETYPE.ACTIVE_START:e.bounds.newActivation(t,y);break;case r.yy.LINETYPE.ACTIVE_END:h(t,e.bounds.getVerticalPos());break;case r.yy.LINETYPE.LOOP_START:e.bounds.bumpVerticalPos(s.boxMargin),e.bounds.newLoop(t.message),e.bounds.bumpVerticalPos(s.boxMargin+s.boxTextMargin);break;case r.yy.LINETYPE.LOOP_END:n=e.bounds.endLoop(),i.drawLoop(y,n,"loop",s),e.bounds.bumpVerticalPos(s.boxMargin);break;case r.yy.LINETYPE.OPT_START:e.bounds.bumpVerticalPos(s.boxMargin),e.bounds.newLoop(t.message),e.bounds.bumpVerticalPos(s.boxMargin+s.boxTextMargin);break;case r.yy.LINETYPE.OPT_END:n=e.bounds.endLoop(),i.drawLoop(y,n,"opt",s),e.bounds.bumpVerticalPos(s.boxMargin);break;case r.yy.LINETYPE.ALT_START:e.bounds.bumpVerticalPos(s.boxMargin),e.bounds.newLoop(t.message),e.bounds.bumpVerticalPos(s.boxMargin+s.boxTextMargin);break;case r.yy.LINETYPE.ALT_ELSE:e.bounds.bumpVerticalPos(s.boxMargin),n=e.bounds.addElseToLoop(t.message),e.bounds.bumpVerticalPos(s.boxMargin);break;case r.yy.LINETYPE.ALT_END:n=e.bounds.endLoop(),i.drawLoop(y,n,"alt",s),e.bounds.bumpVerticalPos(s.boxMargin);break;default:try{x=t,e.bounds.bumpVerticalPos(s.messageMargin);var a=f(t.from),u=f(t.to),o=a[0]<=u[0]?1:0,v=a[0]/gi," "),i=t.append("text");i.attr("x",n.x),i.attr("y",n.y),i.style("text-anchor",n.anchor),i.attr("fill",n.fill),"undefined"!=typeof n["class"]&&i.attr("class",n["class"]);var a=i.append("tspan");return a.attr("x",n.x+2*n.textMargin),a.text(r),"undefined"!=typeof i.textwrap&&i.textwrap({x:n.x,y:n.y,width:e,height:1800},n.textMargin),i},e.drawLabel=function(t,n){var r=e.getNoteRect();r.x=n.x,r.y=n.y,r.width=50,r.height=20,r.fill="#526e52",r.stroke="none",r["class"]="labelBox",e.drawRect(t,r),n.y=n.y+n.labelMargin,n.x=n.x+.5*n.labelMargin,n.fill="white",e.drawText(t,n)};var r=-1;e.drawActor=function(t,n,a,u,o){var s=n+o.width/2,c=t.append("g");0===a&&(r++,c.append("line").attr("id","actor"+r).attr("x1",s).attr("y1",5).attr("x2",s).attr("y2",2e3).attr("class","actor-line").attr("stroke-width","0.5px").attr("stroke","#999"));var l=e.getNoteRect();l.x=n,l.y=a,l.fill="#eaeaea",l.width=o.width,l.height=o.height,l["class"]="actor",l.rx=3,l.ry=3,e.drawRect(c,l),i(o)(u,c,l.x,l.y,l.width,l.height,{"class":"actor"})},e.anchorElement=function(t){return t.append("g")},e.drawActivation=function(t,n,r){var i=e.getNoteRect(),a=n.anchored;i.x=n.startx,i.y=n.starty,i.fill="#f4f4f4",i.width=n.stopx-n.startx,i.height=r-n.starty,e.drawRect(a,i)},e.drawLoop=function(t,n,r,i){var a=t.append("g"),u=function(t,n,e,r){a.append("line").attr("x1",t).attr("y1",n).attr("x2",e).attr("y2",r).attr("stroke-width",2).attr("stroke","#526e52").attr("class","loopLine")};u(n.startx,n.starty,n.stopx,n.starty),u(n.stopx,n.starty,n.stopx,n.stopy),u(n.startx,n.stopy,n.stopx,n.stopy),u(n.startx,n.starty,n.startx,n.stopy),"undefined"!=typeof n.elsey&&u(n.startx,n.elsey,n.stopx,n.elsey);var o=e.getTextObj();o.text=r,o.x=n.startx,o.y=n.starty,o.labelMargin=15,o["class"]="labelText",o.fill="white",e.drawLabel(a,o),o=e.getTextObj(),o.text="[ "+n.title+" ]",o.x=n.startx+(n.stopx-n.startx)/2,o.y=n.starty+1.5*i.boxMargin,o.anchor="middle",o["class"]="loopText",e.drawText(a,o),"undefined"!=typeof n.elseText&&(o.text="[ "+n.elseText+" ]",o.y=n.elsey+1.5*i.boxMargin,e.drawText(a,o))},e.insertArrowHead=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")},e.insertArrowCrossHead=function(t){var n=t.append("defs"),e=n.append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",16).attr("refY",4);e.append("path").attr("fill","black").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 9,2 V 6 L16,4 Z"),e.append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 0,1 L 6,7 M 6,1 L 0,7")},e.getTextObj=function(){var t={x:0,y:0,fill:"black","text-anchor":"start",style:"#666",width:100,height:100,textMargin:0,rx:0,ry:0};return t},e.getNoteRect=function(){var t={x:0,y:0,fill:"#EDF2AE",stroke:"#666",width:100,anchor:"start",height:100,rx:0,ry:0};return t};var i=function(){function t(t,n,e,i,a,u,o){var s=n.append("text").attr("x",e+a/2).attr("y",i+u/2+5).style("text-anchor","middle").text(t);r(s,o)}function n(t,n,e,i,a,u,o){var s=n.append("text").attr("x",e+a/2).attr("y",i).style("text-anchor","middle");if(s.append("tspan").attr("x",e+a/2).attr("dy","0").text(t),"undefined"!=typeof s.textwrap){s.textwrap({x:e+a/2,y:i,width:a,height:u},0);var c=s.selectAll("tspan");c.length>0&&c[0].length>0&&(c=c[0],s.attr("y",i+(u/2-s[0][0].getBBox().height*(1-1/c.length)/2)).attr("dominant-baseline","central").attr("alignment-baseline","central"))}r(s,o)}function e(t,e,i,a,u,o,s){var c=e.append("switch"),l=c.append("foreignObject").attr("x",i).attr("y",a).attr("width",u).attr("height",o),h=l.append("div").style("display","table").style("height","100%").style("width","100%");h.append("div").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),n(t,c,i,a,u,o,s),r(h,s)}function r(t,n){for(var e in n)n.hasOwnProperty(e)&&t.attr(e,n[e])}return function(r){return"fo"===r.textPlacement?e:"old"===r.textPlacement?t:n}}()},{}],130:[function(t,n,e){"use strict";function r(t){var n=t.getUTCHours(),e=t.getUTCMinutes(),r=t.getSeconds(),i=t.getMilliseconds();10>n&&(n="0"+n),10>e&&(e="0"+e),10>r&&(r="0"+r),100>i&&(i="0"+i),10>i&&(i="00"+i);var a=n+":"+e+":"+r+" ("+i+")";return a}function i(t){var n=r(new Date);return"%c "+n+" :%c"+t+": "}function a(t){this.level=t,this.log=function(){var t=Array.prototype.slice.call(arguments),n=t.shift(),e=this.level;"undefined"==typeof e&&(e=o),n>=e&&"undefined"!=typeof console&&"undefined"!=typeof console.log&&(t.unshift("["+r(new Date)+"] "),console.log.apply(console,t.map(function(t){return"object"==typeof t?t.toString()+JSON.stringify(t,null,2):t})))},this.trace=window.console.debug.bind(window.console,i("TRACE",name),"color:grey;","color: grey;"),this.debug=window.console.debug.bind(window.console,i("DEBUG",name),"color:grey;","color: green;"),this.info=window.console.debug.bind(window.console,i("INFO",name),"color:grey;","color: blue;"),this.warn=window.console.debug.bind(window.console,i("WARN",name),"color:grey;","color: orange;"),this.error=window.console.debug.bind(window.console,i("ERROR",name),"color:grey;","color: red;")}var u={debug:1,info:2,warn:3,error:4,fatal:5,"default":5},o=u.error;e.setLogLevel=function(t){o=t},e.Log=a},{}],131:[function(t,n,e){(function(n){"use strict";var r=t("./logger"),i=new r.Log,a=t("./diagrams/flowchart/graphDb"),u=t("./utils"),o=t("./diagrams/flowchart/flowRenderer"),s=t("./diagrams/sequenceDiagram/sequenceRenderer"),c=t("./diagrams/example/exampleRenderer"),l=t("./diagrams/example/parser/example"),h=t("./diagrams/flowchart/parser/flow"),f=t("./diagrams/flowchart/parser/dot"),d=t("./diagrams/sequenceDiagram/parser/sequenceDiagram"),p=t("./diagrams/sequenceDiagram/sequenceDb"),g=t("./diagrams/example/exampleDb"),y=t("./diagrams/gantt/ganttRenderer"),m=t("./diagrams/gantt/parser/gantt"),v=t("./diagrams/gantt/ganttDb"),_=t("./diagrams/classDiagram/parser/classDiagram"),b=t("./diagrams/classDiagram/classRenderer"),x=t("./diagrams/classDiagram/classDb"),w=t("./diagrams/gitGraph/parser/gitGraph"),A=t("./diagrams/gitGraph/gitGraphRenderer"),k=t("./diagrams/gitGraph/gitGraphAst"),E=t("./d3");SVGElement.prototype.getTransformToElement=SVGElement.prototype.getTransformToElement||function(t){return t.getScreenCTM().inverse().multiply(this.getScreenCTM())};var M={logLevel:5,cloneCssStyles:!0,startOnLoad:!0,arrowMarkerAbsolute:!1,flowchart:{htmlLabels:!0,useMaxWidth:!0},sequenceDiagram:{diagramMarginX:50,diagramMarginY:10,actorMargin:50,width:150,height:65,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,mirrorActors:!0,bottomMarginAdj:1,useMaxWidth:!0},gantt:{titleTopMargin:25,barHeight:20,barGap:4,topPadding:50,leftPadding:75,gridLineStartPadding:35,fontSize:11,fontFamily:'"Open-Sans", "sans-serif"',numberSectionStyles:3,axisFormatter:[["%I:%M",function(t){return t.getHours()}],["w. %U",function(t){return 1==t.getDay()}],["%a %d",function(t){return t.getDay()&&1!=t.getDate()}],["%b %d",function(t){return 1!=t.getDate()}],["%m-%y",function(t){return t.getMonth()}]]},classDiagram:{},gitGraph:{},info:{}};r.setLogLevel(M.logLevel);var S=function(t){var n,e=u.detectType(t);switch(e){case"gitGraph":n=w,n.parser.yy=k;break;case"graph":n=h,n.parser.yy=a;break;case"dotGraph":n=f,n.parser.yy=a;break;case"sequenceDiagram":n=d,n.parser.yy=p;break;case"info":n=l,n.parser.yy=g;break;case"gantt":n=m,n.parser.yy=v;break;case"classDiagram":n=_,n.parser.yy=x}try{return n.parse(t),!0}catch(r){return!1}};e.parse=S,e.version=function(){return t("../package.json").version},e.encodeEntities=function(t){var n=t;return n=n.replace(/style.*:\S*#.*;/g,function(t){var n=t.substring(0,t.length-1);return n}),n=n.replace(/classDef.*:\S*#.*;/g,function(t){var n=t.substring(0,t.length-1);return n}),n=n.replace(/#\w+\;/g,function(t){var n=t.substring(1,t.length-1),e=/^\+?\d+$/.test(n);return e?"fl°°"+n+"¶ß":"fl°"+n+"¶ß"})},e.decodeEntities=function(t){var n=t;return n=n.replace(/\fl\°\°/g,function(){return"&#"}),n=n.replace(/\fl\°/g,function(){return"&"}),n=n.replace(/¶ß/g,function(){return";"})};var D=function(t,n,r,l){if("undefined"!=typeof l)l.innerHTML="",E.select(l).append("div").attr("id","d"+t).append("svg").attr("id",t).attr("width","100%").attr("xmlns","http://www.w3.org/2000/svg").append("g");else{var h=document.querySelector("#d"+t);h&&(h.innerHTML=""),E.select("body").append("div").attr("id","d"+t).append("svg").attr("id",t).attr("width","100%").attr("xmlns","http://www.w3.org/2000/svg").append("g")}window.txt=n,n=e.encodeEntities(n);var h=E.select("#d"+t).node(),f=u.detectType(n),d={};switch(f){case"gitGraph":M.flowchart.arrowMarkerAbsolute=M.arrowMarkerAbsolute,A.setConf(M.gitGraph),A.draw(n,t,!1);break;case"graph":M.flowchart.arrowMarkerAbsolute=M.arrowMarkerAbsolute,o.setConf(M.flowchart),o.draw(n,t,!1),M.cloneCssStyles&&(d=o.getClasses(n,!1),u.cloneCssStyles(h.firstChild,d));break;case"dotGraph":M.flowchart.arrowMarkerAbsolute=M.arrowMarkerAbsolute,o.setConf(M.flowchart),o.draw(n,t,!0),M.cloneCssStyles&&(d=o.getClasses(n,!0),u.cloneCssStyles(h.firstChild,d));break;case"sequenceDiagram":M.sequenceDiagram.arrowMarkerAbsolute=M.arrowMarkerAbsolute,s.setConf(M.sequenceDiagram),s.draw(n,t),M.cloneCssStyles&&u.cloneCssStyles(h.firstChild,[]);break;case"gantt":M.gantt.arrowMarkerAbsolute=M.arrowMarkerAbsolute,y.setConf(M.gantt),y.draw(n,t),M.cloneCssStyles&&u.cloneCssStyles(h.firstChild,[]);break;case"classDiagram":M.classDiagram.arrowMarkerAbsolute=M.arrowMarkerAbsolute,b.setConf(M.classDiagram),b.draw(n,t),M.cloneCssStyles&&u.cloneCssStyles(h.firstChild,[]);break;case"info":M.info.arrowMarkerAbsolute=M.arrowMarkerAbsolute,c.draw(n,t,e.version()),M.cloneCssStyles&&u.cloneCssStyles(h.firstChild,[])}E.select("#d"+t).selectAll("foreignobject div").attr("xmlns","http://www.w3.org/1999/xhtml");var p="";M.arrowMarkerAbsolute&&(p=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,p=p.replace(/\(/g,"\\("),p=p.replace(/\)/g,"\\)"));var g=E.select("#d"+t).node().innerHTML.replace(/url\(#arrowhead/g,"url("+p+"#arrowhead","g");g=e.decodeEntities(g),"undefined"!=typeof r?r(g,a.bindFunctions):i.warn("CB = undefined!");var m=E.select("#d"+t).node();return null!==m&&"function"==typeof m.remove&&E.select("#d"+t).node().remove(),g};e.render=function(t,n,e,r){try{if(1===arguments.length&&(n=t,t="mermaidId0"),"undefined"!=typeof document)return D(t,n,e,r)}catch(a){i.warn(a)}};var C=function(t){var n,e=Object.keys(t);for(n=0;n0&&(r+=e.selectorText+" { "+e.style.cssText+"}\n")}}catch(l){"undefined"!=typeof e&&i.warn('Invalid CSS selector "'+e.selectorText+'"',l)}var h="",f="";for(var d in n)n.hasOwnProperty(d)&&"undefined"!=typeof d&&("default"===d?(n["default"].styles instanceof Array&&(h+="#"+t.id.trim()+" .node>rect { "+n[d].styles.join("; ")+"; }\n"),n["default"].nodeLabelStyles instanceof Array&&(h+="#"+t.id.trim()+" .node text { "+n[d].nodeLabelStyles.join("; ")+"; }\n"),n["default"].edgeLabelStyles instanceof Array&&(h+="#"+t.id.trim()+" .edgeLabel text { "+n[d].edgeLabelStyles.join("; ")+"; }\n"),n["default"].clusterStyles instanceof Array&&(h+="#"+t.id.trim()+" .cluster rect { "+n[d].clusterStyles.join("; ")+"; }\n")):n[d].styles instanceof Array&&(f+="#"+t.id.trim()+" ."+d+">rect, ."+d+">polygon, ."+d+">circle, ."+d+">ellipse { "+n[d].styles.join("; ")+"; }\n"));if(""!==r||""!==h||""!==f){var p=document.createElement("style");p.setAttribute("type","text/css"),p.setAttribute("title","mermaid-svg-internal-css"),p.innerHTML="/* */\n",t.insertBefore(p,t.firstChild)}};e.cloneCssStyles=u;var o=function(t,n){for(var e=0;e" + source + "", 'text/html'); - var eles = htmlDoc.querySelectorAll("h1, h2, h3, h4, h5, h6"); - - for (var i = 0; i < eles.length; ++i) { - var ele = eles[i]; - var level = parseInt(ele.tagName.substr(1)); - var escapedText = 'toc_' + nameCounter++; - - toc.push({ - level: level, - anchor: escapedText, - title: ele.innerText - }); - - ele.setAttribute('id', escapedText); - } - - var html = htmlDoc.getElementById('showdown-container').innerHTML; - - delete parser; - - return html; - } - }; - - return [headinganchor]; - }); -})); diff --git a/src/utils/showdown/showdown.min.js b/src/utils/showdown/showdown.min.js deleted file mode 100644 index 5faf821c..00000000 --- a/src/utils/showdown/showdown.min.js +++ /dev/null @@ -1,5 +0,0 @@ -/*! showdown 23-04-2017 */ - -(function(){function a(a){"use strict";var b={omitExtraWLInCodeBlocks:{defaultValue:!1,describe:"Omit the default extra whiteline added to code blocks",type:"boolean"},noHeaderId:{defaultValue:!1,describe:"Turn on/off generated header id",type:"boolean"},prefixHeaderId:{defaultValue:!1,describe:"Specify a prefix to generated header ids",type:"string"},ghCompatibleHeaderId:{defaultValue:!1,describe:"Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)",type:"boolean"},headerLevelStart:{defaultValue:!1,describe:"The header blocks level start",type:"integer"},parseImgDimensions:{defaultValue:!1,describe:"Turn on/off image dimension parsing",type:"boolean"},simplifiedAutoLink:{defaultValue:!1,describe:"Turn on/off GFM autolink style",type:"boolean"},excludeTrailingPunctuationFromURLs:{defaultValue:!1,describe:"Excludes trailing punctuation from links generated with autoLinking",type:"boolean"},literalMidWordUnderscores:{defaultValue:!1,describe:"Parse midword underscores as literal underscores",type:"boolean"},literalMidWordAsterisks:{defaultValue:!1,describe:"Parse midword asterisks as literal asterisks",type:"boolean"},strikethrough:{defaultValue:!1,describe:"Turn on/off strikethrough support",type:"boolean"},tables:{defaultValue:!1,describe:"Turn on/off tables support",type:"boolean"},tablesHeaderId:{defaultValue:!1,describe:"Add an id to table headers",type:"boolean"},ghCodeBlocks:{defaultValue:!0,describe:"Turn on/off GFM fenced code blocks support",type:"boolean"},tasklists:{defaultValue:!1,describe:"Turn on/off GFM tasklist support",type:"boolean"},smoothLivePreview:{defaultValue:!1,describe:"Prevents weird effects in live previews due to incomplete input",type:"boolean"},smartIndentationFix:{defaultValue:!1,description:"Tries to smartly fix indentation in es6 strings",type:"boolean"},disableForced4SpacesIndentedSublists:{defaultValue:!1,description:"Disables the requirement of indenting nested sublists by 4 spaces",type:"boolean"},simpleLineBreaks:{defaultValue:!1,description:"Parses simple line breaks as
    (GFM Style)",type:"boolean"},requireSpaceBeforeHeadingText:{defaultValue:!1,description:"Makes adding a space between `#` and the header text mandatory (GFM Style)",type:"boolean"},ghMentions:{defaultValue:!1,description:"Enables github @mentions",type:"boolean"},ghMentionsLink:{defaultValue:"https://github.com/{u}",description:"Changes the link generated by @mentions. Only applies if ghMentions option is enabled.",type:"string"},encodeEmails:{defaultValue:!0,description:"Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities",type:"boolean"},openLinksInNewWindow:{defaultValue:!1,description:"Open all links in new windows",type:"boolean"}};if(a===!1)return JSON.parse(JSON.stringify(b));var c={};for(var d in b)b.hasOwnProperty(d)&&(c[d]=b[d].defaultValue);return c}function b(){"use strict";var b=a(!0),c={};for(var d in b)b.hasOwnProperty(d)&&(c[d]=!0);return c}function c(a,b){"use strict";var c=b?"Error in "+b+" extension->":"Error in unnamed extension",d={valid:!0,error:""};e.helper.isArray(a)||(a=[a]);for(var f=0;f-1,l=new RegExp(b+"|"+c,"g"+j.replace(/g/g,"")),m=new RegExp(b,j.replace(/g/g,"")),n=[];do for(e=0;g=l.exec(a);)if(m.test(g[0]))e++||(f=l.lastIndex,h=f-g[0].length);else if(e&&!--e){i=g.index+g[0].length;var o={left:{start:h,end:f},match:{start:f,end:g.index},right:{start:g.index,end:i},wholeMatch:{start:h,end:i}};if(n.push(o),!k)return n}while(e&&(l.lastIndex=f));return n};e.helper.matchRecursiveRegExp=function(a,b,c,d){"use strict";for(var e=k(a,b,c,d),f=[],g=0;g0){var l=[];0!==h[0].wholeMatch.start&&l.push(a.slice(0,h[0].wholeMatch.start));for(var m=0;m.9?b[2](a):c>.45?b[1](a):b[0](a)}return a})},"undefined"==typeof console&&(console={warn:function(a){"use strict";alert(a)},log:function(a){"use strict";alert(a)},error:function(a){"use strict";throw a}}),e.helper.regexes={asteriskAndDash:/([*_])/g},e.Converter=function(a){"use strict";function b(){a=a||{};for(var b in h)h.hasOwnProperty(b)&&(m[b]=h[b]);if("object"!=typeof a)throw Error("Converter expects the passed parameter to be an object, but "+typeof a+" was passed instead.");for(var c in a)a.hasOwnProperty(c)&&(m[c]=a[c]);m.extensions&&e.helper.forEach(m.extensions,d)}function d(a,b){if(b=b||null,e.helper.isString(a)){if(a=e.helper.stdExtName(a),b=a,e.extensions[a])return console.warn("DEPRECATION WARNING: "+a+" is an old extension that uses a deprecated loading method.Please inform the developer that the extension should be updated!"),void f(e.extensions[a],a);if(e.helper.isUndefined(g[a]))throw Error('Extension "'+a+'" could not be loaded. It was either not found or is not a valid extension.');a=g[a]}"function"==typeof a&&(a=a()),e.helper.isArray(a)||(a=[a]);var d=c(a,b);if(!d.valid)throw Error(d.error);for(var h=0;h-1))return a;n=""}else n=c.gUrls[m],e.helper.isUndefined(c.gTitles[m])||(o=c.gTitles[m]);n=n.replace(e.helper.regexes.asteriskAndDash,e.helper.escapeCharactersCallback);var p='"};return a=a.replace(/(\[((?:\[[^\]]*]|[^\[\]])*)][ ]?(?:\n[ ]*)?\[(.*?)])()()()()/g,d),a=a.replace(/(\[((?:\[[^\]]*]|[^\[\]])*)]\([ \t]*()?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,d),a=a.replace(/(\[([^\[\]]+)])()()()()()/g,d),b.ghMentions&&(a=a.replace(/(^|\s)(\\)?(@([a-z\d\-]+))(?=[.!?;,[\]()]|\s|$)/gim,function(a,c,d,f,g){if("\\"===d)return c+f;if(!e.helper.isString(b.ghMentionsLink))throw new Error("ghMentionsLink option must be a string");var h=b.ghMentionsLink.replace(/\{u}/g,g);return c+''+f+""})),a=c.converter._dispatch("anchors.after",a,b,c)});var l=/\b(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+)()(?=\s|$)(?!["<>])/gi,m=/\b(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]]?)(?=\s|$)(?!["<>])/gi,n=/<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)>/gi,o=/(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-\/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gim,p=/<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,q=function(a){"use strict";return function(b,c,d,e,f){var g=c,h="",i="";return/^www\./i.test(c)&&(c=c.replace(/^www\./i,"http://www.")),a.excludeTrailingPunctuationFromURLs&&f&&(h=f),a.openLinksInNewWindow&&(i=' target="_blank"'),'"+g+""+h}},r=function(a,b){"use strict";return function(c,d,f){var g="mailto:";return d=d||"",f=e.subParser("unescapeSpecialChars")(f,a,b),a.encodeEmails?(g=e.helper.encodeEmailAddress(g+f),f=e.helper.encodeEmailAddress(f)):g+=f,d+''+f+""}};e.subParser("autoLinks",function(a,b,c){"use strict";return a=c.converter._dispatch("autoLinks.before",a,b,c),a=a.replace(n,q(b)),a=a.replace(p,r(b,c)),a=c.converter._dispatch("autoLinks.after",a,b,c)}),e.subParser("simplifiedAutoLinks",function(a,b,c){"use strict";return b.simplifiedAutoLink?(a=c.converter._dispatch("simplifiedAutoLinks.before",a,b,c),a=b.excludeTrailingPunctuationFromURLs?a.replace(m,q(b)):a.replace(l,q(b)),a=a.replace(o,r(b,c)),a=c.converter._dispatch("simplifiedAutoLinks.after",a,b,c)):a}),e.subParser("blockGamut",function(a,b,c){"use strict";return a=c.converter._dispatch("blockGamut.before",a,b,c),a=e.subParser("blockQuotes")(a,b,c),a=e.subParser("headers")(a,b,c),a=e.subParser("horizontalRule")(a,b,c),a=e.subParser("lists")(a,b,c),a=e.subParser("codeBlocks")(a,b,c),a=e.subParser("tables")(a,b,c),a=e.subParser("hashHTMLBlocks")(a,b,c),a=e.subParser("paragraphs")(a,b,c),a=c.converter._dispatch("blockGamut.after",a,b,c)}),e.subParser("blockQuotes",function(a,b,c){"use strict";return a=c.converter._dispatch("blockQuotes.before",a,b,c),a=a.replace(/((^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+)/gm,function(a,d){var f=d;return f=f.replace(/^[ \t]*>[ \t]?/gm,"¨0"),f=f.replace(/¨0/g,""),f=f.replace(/^[ \t]+$/gm,""),f=e.subParser("githubCodeBlocks")(f,b,c),f=e.subParser("blockGamut")(f,b,c),f=f.replace(/(^|\n)/g,"$1 "),f=f.replace(/(\s*
    [^\r]+?<\/pre>)/gm,function(a,b){var c=b;return c=c.replace(/^  /gm,"¨0"),c=c.replace(/¨0/g,"")}),e.subParser("hashBlock")("
    \n"+f+"\n
    ",b,c)}),a=c.converter._dispatch("blockQuotes.after",a,b,c)}),e.subParser("codeBlocks",function(a,b,c){"use strict";a=c.converter._dispatch("codeBlocks.before",a,b,c),a+="¨0";var d=/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g;return a=a.replace(d,function(a,d,f){var g=d,h=f,i="\n";return g=e.subParser("outdent")(g,b,c),g=e.subParser("encodeCode")(g,b,c),g=e.subParser("detab")(g,b,c),g=g.replace(/^\n+/g,""),g=g.replace(/\n+$/g,""),b.omitExtraWLInCodeBlocks&&(i=""),g="
    "+g+i+"
    ",e.subParser("hashBlock")(g,b,c)+h}),a=a.replace(/¨0/,""),a=c.converter._dispatch("codeBlocks.after",a,b,c)}),e.subParser("codeSpans",function(a,b,c){"use strict";return a=c.converter._dispatch("codeSpans.before",a,b,c),"undefined"==typeof a&&(a=""),a=a.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,function(a,d,f,g){var h=g;return h=h.replace(/^([ \t]*)/g,""),h=h.replace(/[ \t]*$/g,""),h=e.subParser("encodeCode")(h,b,c),d+""+h+""}),a=c.converter._dispatch("codeSpans.after",a,b,c)}),e.subParser("detab",function(a,b,c){"use strict";return a=c.converter._dispatch("detab.before",a,b,c),a=a.replace(/\t(?=\t)/g," "),a=a.replace(/\t/g,"¨A¨B"),a=a.replace(/¨B(.+?)¨A/g,function(a,b){for(var c=b,d=4-c.length%4,e=0;e/g,">"),a=c.converter._dispatch("encodeAmpsAndAngles.after",a,b,c)}),e.subParser("encodeBackslashEscapes",function(a,b,c){"use strict";return a=c.converter._dispatch("encodeBackslashEscapes.before",a,b,c),a=a.replace(/\\(\\)/g,e.helper.escapeCharactersCallback),a=a.replace(/\\([`*_{}\[\]()>#+.!~=|-])/g,e.helper.escapeCharactersCallback),a=c.converter._dispatch("encodeBackslashEscapes.after",a,b,c)}),e.subParser("encodeCode",function(a,b,c){"use strict";return a=c.converter._dispatch("encodeCode.before",a,b,c),a=a.replace(/&/g,"&").replace(//g,">").replace(/([*_{}\[\]\\=~-])/g,e.helper.escapeCharactersCallback),a=c.converter._dispatch("encodeCode.after",a,b,c)}),e.subParser("escapeSpecialCharsWithinTagAttributes",function(a,b,c){"use strict";a=c.converter._dispatch("escapeSpecialCharsWithinTagAttributes.before",a,b,c);var d=/(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|)/gi;return a=a.replace(d,function(a){return a.replace(/(.)<\/?code>(?=.)/g,"$1`").replace(/([\\`*_~=|])/g,e.helper.escapeCharactersCallback)}),a=c.converter._dispatch("escapeSpecialCharsWithinTagAttributes.after",a,b,c)}),e.subParser("githubCodeBlocks",function(a,b,c){"use strict";return b.ghCodeBlocks?(a=c.converter._dispatch("githubCodeBlocks.before",a,b,c),a+="¨0",a=a.replace(/(?:^|\n)```(.*)\n([\s\S]*?)\n```/g,function(a,d,f){var g=b.omitExtraWLInCodeBlocks?"":"\n";return f=e.subParser("encodeCode")(f,b,c),f=e.subParser("detab")(f,b,c),f=f.replace(/^\n+/g,""),f=f.replace(/\n+$/g,""),f="
    "+f+g+"
    ",f=e.subParser("hashBlock")(f,b,c),"\n\n¨G"+(c.ghCodeBlocks.push({text:a,codeblock:f})-1)+"G\n\n"}),a=a.replace(/¨0/,""),c.converter._dispatch("githubCodeBlocks.after",a,b,c)):a}),e.subParser("hashBlock",function(a,b,c){"use strict";return a=c.converter._dispatch("hashBlock.before",a,b,c),a=a.replace(/(^\n+|\n+$)/g,""),a="\n\n¨K"+(c.gHtmlBlocks.push(a)-1)+"K\n\n",a=c.converter._dispatch("hashBlock.after",a,b,c)}),e.subParser("hashCodeTags",function(a,b,c){"use strict";a=c.converter._dispatch("hashCodeTags.before",a,b,c);var d=function(a,d,f,g){var h=f+e.subParser("encodeCode")(d,b,c)+g;return"¨C"+(c.gHtmlSpans.push(h)-1)+"C"};return a=e.helper.replaceRecursiveRegExp(a,d,"]*>","","gim"),a=c.converter._dispatch("hashCodeTags.after",a,b,c)}),e.subParser("hashElement",function(a,b,c){"use strict";return function(a,b){var d=b;return d=d.replace(/\n\n/g,"\n"),d=d.replace(/^\n/,""),d=d.replace(/\n+$/g,""),d="\n\n¨K"+(c.gHtmlBlocks.push(d)-1)+"K\n\n"}}),e.subParser("hashHTMLBlocks",function(a,b,c){"use strict";a=c.converter._dispatch("hashHTMLBlocks.before",a,b,c);for(var d=["pre","div","h1","h2","h3","h4","h5","h6","blockquote","table","dl","ol","ul","script","noscript","form","fieldset","iframe","math","style","section","header","footer","nav","article","aside","address","audio","canvas","figure","hgroup","output","video","p"],f=function(a,b,d,e){var f=a;return d.search(/\bmarkdown\b/)!==-1&&(f=d+c.converter.makeHtml(b)+e),"\n\n¨K"+(c.gHtmlBlocks.push(f)-1)+"K\n\n"},g=0;g]*>","","gim");return a=a.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,e.subParser("hashElement")(a,b,c)),a=e.helper.replaceRecursiveRegExp(a,function(a){return"\n\n¨K"+(c.gHtmlBlocks.push(a)-1)+"K\n\n"},"^ {0,3}","gm"),a=a.replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,e.subParser("hashElement")(a,b,c)),a=c.converter._dispatch("hashHTMLBlocks.after",a,b,c)}),e.subParser("hashHTMLSpans",function(a,b,c){"use strict";function d(a){return"¨C"+(c.gHtmlSpans.push(a)-1)+"C"}return a=c.converter._dispatch("hashHTMLSpans.before",a,b,c),a=a.replace(/<[^>]+?\/>/gi,function(a){return d(a)}),a=a.replace(/<([^>]+?)>[\s\S]*?<\/\1>/g,function(a){return d(a)}),a=a.replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g,function(a){return d(a)}),a=a.replace(/<[^>]+?>/gi,function(a){return d(a)}),a=c.converter._dispatch("hashHTMLSpans.after",a,b,c)}),e.subParser("unhashHTMLSpans",function(a,b,c){"use strict";a=c.converter._dispatch("unhashHTMLSpans.before",a,b,c);for(var d=0;d]*>\\s*]*>","^ {0,3}\\s*
    ","gim"),a=c.converter._dispatch("hashPreCodeTags.after",a,b,c)}),e.subParser("headers",function(a,b,c){"use strict";function d(a){var d;return d=e.helper.isString(b.prefixHeaderId)?b.prefixHeaderId+a:b.prefixHeaderId===!0?"section "+a:a,d=g?d.replace(/ /g,"-").replace(/&/g,"").replace(/¨T/g,"").replace(/¨D/g,"").replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g,"").toLowerCase():d.replace(/[^\w]/g,"").toLowerCase(),c.hashLinkCounts[d]?d=d+"-"+c.hashLinkCounts[d]++:c.hashLinkCounts[d]=1,d}a=c.converter._dispatch("headers.before",a,b,c);var f=isNaN(parseInt(b.headerLevelStart))?1:parseInt(b.headerLevelStart),g=b.ghCompatibleHeaderId,h=b.smoothLivePreview?/^(.+)[ \t]*\n={2,}[ \t]*\n+/gm:/^(.+)[ \t]*\n=+[ \t]*\n+/gm,i=b.smoothLivePreview?/^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm:/^(.+)[ \t]*\n-+[ \t]*\n+/gm;a=a.replace(h,function(a,g){var h=e.subParser("spanGamut")(g,b,c),i=b.noHeaderId?"":' id="'+d(g)+'"',j=f,k=""+h+"";return e.subParser("hashBlock")(k,b,c)}),a=a.replace(i,function(a,g){var h=e.subParser("spanGamut")(g,b,c),i=b.noHeaderId?"":' id="'+d(g)+'"',j=f+1,k=""+h+"";return e.subParser("hashBlock")(k,b,c)});var j=b.requireSpaceBeforeHeadingText?/^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm:/^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm;return a=a.replace(j,function(a,g,h){var i=e.subParser("spanGamut")(h,b,c),j=b.noHeaderId?"":' id="'+d(h)+'"',k=f-1+g.length,l=""+i+"";return e.subParser("hashBlock")(l,b,c)}),a=c.converter._dispatch("headers.after",a,b,c)}),e.subParser("horizontalRule",function(a,b,c){"use strict";a=c.converter._dispatch("horizontalRule.before",a,b,c);var d=e.subParser("hashBlock")("
    ",b,c);return a=a.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm,d),a=a.replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm,d),a=a.replace(/^ {0,2}( ?_){3,}[ \t]*$/gm,d),a=c.converter._dispatch("horizontalRule.after",a,b,c)}),e.subParser("images",function(a,b,c){"use strict";function d(a,b,d,f,g,h,i,j){var k=c.gUrls,l=c.gTitles,m=c.gDimensions;if(d=d.toLowerCase(),j||(j=""),""===f||null===f){if(""!==d&&null!==d||(d=b.toLowerCase().replace(/ ?\n/g," ")),f="#"+d,e.helper.isUndefined(k[d]))return a;f=k[d],e.helper.isUndefined(l[d])||(j=l[d]),e.helper.isUndefined(m[d])||(g=m[d].width,h=m[d].height)}b=b.replace(/"/g,""").replace(e.helper.regexes.asteriskAndDash,e.helper.escapeCharactersCallback),f=f.replace(e.helper.regexes.asteriskAndDash,e.helper.escapeCharactersCallback);var n=''+b+'?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(['"])(.*?)\6[ \t]*)?\)/g,g=/!\[([^\]]*?)] ?(?:\n *)?\[(.*?)]()()()()()/g,h=/!\[([^\[\]]+)]()()()()()/g;return a=a.replace(g,d),a=a.replace(f,d),a=a.replace(h,d),a=c.converter._dispatch("images.after",a,b,c)}),e.subParser("italicsAndBold",function(a,b,c){"use strict";function d(a,d,f){return b.simplifiedAutoLink&&(a=e.subParser("simplifiedAutoLinks")(a,b,c)),d+a+f}return a=c.converter._dispatch("italicsAndBold.before",a,b,c),b.literalMidWordUnderscores?(a=a.replace(/\b___(\S[\s\S]*)___\b/g,function(a,b){return d(b,"","")}),a=a.replace(/\b__(\S[\s\S]*)__\b/g,function(a,b){return d(b,"","")}),a=a.replace(/\b_(\S[\s\S]*?)_\b/g,function(a,b){return d(b,"","")})):(a=a.replace(/___(\S[\s\S]*?)___/g,function(a,b){return/\S$/.test(b)?d(b,"",""):a}),a=a.replace(/__(\S[\s\S]*?)__/g,function(a,b){return/\S$/.test(b)?d(b,"",""):a}),a=a.replace(/_([^\s_][\s\S]*?)_/g,function(a,b){return/\S$/.test(b)?d(b,"",""):a})),b.literalMidWordAsterisks?(a=a.trim().replace(/(?:^| +)\*{3}(\S[\s\S]*?)\*{3}(?: +|$)/g,function(a,b){return d(b," "," ")}),a=a.trim().replace(/(?:^| +)\*{2}(\S[\s\S]*?)\*{2}(?: +|$)/g,function(a,b){return d(b," "," ")}),a=a.trim().replace(/(?:^| +)\*{1}(\S[\s\S]*?)\*{1}(?: +|$)/g,function(a,b){return d(b," ",""+(" "===a.slice(-1)?" ":""))})):(a=a.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g,function(a,b){return/\S$/.test(b)?d(b,"",""):a}),a=a.replace(/\*\*(\S[\s\S]*?)\*\*/g,function(a,b){return/\S$/.test(b)?d(b,"",""):a}),a=a.replace(/\*([^\s*][\s\S]*?)\*/g,function(a,b){return/\S$/.test(b)?d(b,"",""):a})),a=c.converter._dispatch("italicsAndBold.after",a,b,c)}),e.subParser("lists",function(a,b,c){"use strict";function d(a,d){c.gListLevel++,a=a.replace(/\n{2,}$/,"\n"),a+="¨0";var f=/(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm,g=/\n[ \t]*\n(?!¨0)/.test(a);return b.disableForced4SpacesIndentedSublists&&(f=/(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm),a=a.replace(f,function(a,d,f,h,i,j,k){k=k&&""!==k.trim();var l=e.subParser("outdent")(i,b,c),m="";return j&&b.tasklists&&(m=' class="task-list-item" style="list-style-type: none;"',l=l.replace(/^[ \t]*\[(x|X| )?]/m,function(){var a='-1?(l=e.subParser("githubCodeBlocks")(l,b,c),l=e.subParser("blockGamut")(l,b,c)):(l=e.subParser("lists")(l,b,c),l=l.replace(/\n$/,""),l=e.subParser("hashHTMLBlocks")(l,b,c),l=l.replace(/\n\n+/g,"\n\n"),l=l.replace(/\n\n/g,"¨B"),l=g?e.subParser("paragraphs")(l,b,c):e.subParser("spanGamut")(l,b,c),l=l.replace(/¨B/g,"\n\n")),l=l.replace("¨A",""),l=""+l+"\n"}),a=a.replace(/¨0/g,""),c.gListLevel--,d&&(a=a.replace(/\s+$/,"")),a}function f(a,c,e){var f=b.disableForced4SpacesIndentedSublists?/^ ?\d+\.[ \t]/gm:/^ {0,3}\d+\.[ \t]/gm,g=b.disableForced4SpacesIndentedSublists?/^ ?[*+-][ \t]/gm:/^ {0,3}[*+-][ \t]/gm,h="ul"===c?f:g,i="";return a.search(h)!==-1?!function a(b){var j=b.search(h);j!==-1?(i+="\n<"+c+">\n"+d(b.slice(0,j),!!e)+"\n",c="ul"===c?"ol":"ul",h="ul"===c?f:g,a(b.slice(j))):i+="\n<"+c+">\n"+d(b,!!e)+"\n"}(a):i="\n<"+c+">\n"+d(a,!!e)+"\n",i}return a=c.converter._dispatch("lists.before",a,b,c),a+="¨0",a=c.gListLevel?a.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,function(a,b,c){var d=c.search(/[*+-]/g)>-1?"ul":"ol";return f(b,d,!0)}):a.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,function(a,b,c,d){var e=d.search(/[*+-]/g)>-1?"ul":"ol";return f(c,e,!1)}),a=a.replace(/¨0/,""),a=c.converter._dispatch("lists.after",a,b,c)}),e.subParser("outdent",function(a,b,c){"use strict";return a=c.converter._dispatch("outdent.before",a,b,c),a=a.replace(/^(\t|[ ]{1,4})/gm,"¨0"),a=a.replace(/¨0/g,""),a=c.converter._dispatch("outdent.after",a,b,c)}),e.subParser("paragraphs",function(a,b,c){"use strict";a=c.converter._dispatch("paragraphs.before",a,b,c),a=a.replace(/^\n+/g,""),a=a.replace(/\n+$/g,"");for(var d=a.split(/\n{2,}/g),f=[],g=d.length,h=0;h=0?f.push(i):i.search(/\S/)>=0&&(i=e.subParser("spanGamut")(i,b,c),i=i.replace(/^([ \t]*)/g,"

    "),i+="

    ",f.push(i))}for(g=f.length,h=0;h]*>\s*]*>/.test(k)&&(l=!0)}f[h]=k}return a=f.join("\n"),a=a.replace(/^\n+/g,""),a=a.replace(/\n+$/g,""),c.converter._dispatch("paragraphs.after",a,b,c)}),e.subParser("runExtension",function(a,b,c,d){"use strict";if(a.filter)b=a.filter(b,d.converter,c);else if(a.regex){var e=a.regex;e instanceof RegExp||(e=new RegExp(e,"g")),b=b.replace(e,a.replace)}return b}),e.subParser("spanGamut",function(a,b,c){"use strict";return a=c.converter._dispatch("spanGamut.before",a,b,c),a=e.subParser("codeSpans")(a,b,c),a=e.subParser("escapeSpecialCharsWithinTagAttributes")(a,b,c),a=e.subParser("encodeBackslashEscapes")(a,b,c),a=e.subParser("images")(a,b,c),a=e.subParser("anchors")(a,b,c),a=e.subParser("autoLinks")(a,b,c),a=e.subParser("italicsAndBold")(a,b,c),a=e.subParser("strikethrough")(a,b,c),a=e.subParser("simplifiedAutoLinks")(a,b,c),a=e.subParser("hashHTMLSpans")(a,b,c),a=e.subParser("encodeAmpsAndAngles")(a,b,c),a=b.simpleLineBreaks?a.replace(/\n/g,"
    \n"):a.replace(/ +\n/g,"
    \n"),a=c.converter._dispatch("spanGamut.after",a,b,c)}),e.subParser("strikethrough",function(a,b,c){"use strict";function d(a){return b.simplifiedAutoLink&&(a=e.subParser("simplifiedAutoLinks")(a,b,c)),""+a+""}return b.strikethrough&&(a=c.converter._dispatch("strikethrough.before",a,b,c),a=a.replace(/(?:~){2}([\s\S]+?)(?:~){2}/g,function(a,b){return d(b)}),a=c.converter._dispatch("strikethrough.after",a,b,c)),a}),e.subParser("stripLinkDefinitions",function(a,b,c){"use strict";var d=/^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n+|(?=¨0))/gm;return a+="¨0",a=a.replace(d,function(a,d,f,g,h,i,j){return d=d.toLowerCase(),c.gUrls[d]=e.subParser("encodeAmpsAndAngles")(f,b,c),i?i+j:(j&&(c.gTitles[d]=j.replace(/"|'/g,""")),b.parseImgDimensions&&g&&h&&(c.gDimensions[d]={width:g,height:h}),"")}),a=a.replace(/¨0/,"")}),e.subParser("tables",function(a,b,c){"use strict";function d(a){return/^:[ \t]*--*$/.test(a)?' style="text-align:left;"':/^--*[ \t]*:[ \t]*$/.test(a)?' style="text-align:right;"':/^:[ \t]*--*[ \t]*:$/.test(a)?' style="text-align:center;"':""}function f(a,d){var f="";return a=a.trim(),b.tableHeaderId&&(f=' id="'+a.replace(/ /g,"_").toLowerCase()+'"'),a=e.subParser("spanGamut")(a,b,c),""+a+"\n"}function g(a,d){var f=e.subParser("spanGamut")(a,b,c);return""+f+"\n"}function h(a,b){for(var c="\n\n\n",d=a.length,e=0;e\n\n\n",e=0;e\n";for(var f=0;f\n"}return c+="\n
    \n"}if(!b.tables)return a;var i=/^ {0,3}\|?.+\|.+\n[ \t]{0,3}\|?[ \t]*:?[ \t]*(?:-|=){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:-|=){2,}[\s\S]+?(?:\n\n|¨0)/gm;return a=c.converter._dispatch("tables.before",a,b,c),a=a.replace(/\\(\|)/g,e.helper.escapeCharactersCallback),a=a.replace(i,function(a){var b,c=a.split("\n");for(b=0;b - -#include "vutils.h" - -void VClipboardUtils::setImageToClipboard(QClipboard *p_clipboard, - const QImage &p_image, - QClipboard::Mode p_mode) -{ -#if defined(Q_OS_WIN) - // On Windows, setImage() may fail. We will repeatedly retry until succeed. - setImageLoop(p_clipboard, p_image, p_mode); -#else - p_clipboard->setImage(p_image, p_mode); -#endif -} - -void VClipboardUtils::setImageLoop(QClipboard *p_clipboard, - const QImage &p_image, - QClipboard::Mode p_mode) -{ - while (true) { - p_clipboard->setImage(p_image, p_mode); - - QImage image = p_clipboard->image(p_mode); - if (!image.isNull()) { - break; - } - - qDebug() << "fail to set image, retry"; - - VUtils::sleepWait(100 /* ms */); - } -} diff --git a/src/utils/vclipboardutils.h b/src/utils/vclipboardutils.h deleted file mode 100644 index df50b3bc..00000000 --- a/src/utils/vclipboardutils.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef VCLIPBOARDUTILS_H -#define VCLIPBOARDUTILS_H - -#include -#include - - -class VClipboardUtils -{ -public: - static void setImageToClipboard(QClipboard *p_clipboard, - const QImage &p_image, - QClipboard::Mode p_mode = QClipboard::Clipboard); - -private: - VClipboardUtils() - { - } - - static void setImageLoop(QClipboard *p_clipboard, - const QImage &p_image, - QClipboard::Mode p_mode); -}; - -#endif // VCLIPBOARDUTILS_H diff --git a/src/utils/veditutils.cpp b/src/utils/veditutils.cpp deleted file mode 100644 index 7dcab885..00000000 --- a/src/utils/veditutils.cpp +++ /dev/null @@ -1,964 +0,0 @@ -#include "veditutils.h" - -#include -#include -#include -#include -#include - -#include "vutils.h" - -void VEditUtils::removeBlock(QTextBlock &p_block, QString *p_text) -{ - QTextCursor cursor(p_block); - removeBlock(cursor, p_text); -} - -void VEditUtils::removeBlock(QTextCursor &p_cursor, QString *p_text) -{ - const QTextDocument *doc = p_cursor.document(); - int blockCount = doc->blockCount(); - int blockNum = p_cursor.block().blockNumber(); - - p_cursor.select(QTextCursor::BlockUnderCursor); - if (p_text) { - *p_text = selectedText(p_cursor) + "\n"; - } - - p_cursor.deleteChar(); - - // Deleting the first block will leave an empty block. - // Deleting the last empty block will not work with deleteChar(). - if (blockCount == doc->blockCount()) { - if (blockNum == blockCount - 1) { - // The last block. - p_cursor.deletePreviousChar(); - } else { - p_cursor.deleteChar(); - } - } - - if (p_cursor.block().blockNumber() < blockNum) { - p_cursor.movePosition(QTextCursor::NextBlock); - } - - p_cursor.movePosition(QTextCursor::StartOfBlock); -} - -bool VEditUtils::insertBlockWithIndent(QTextCursor &p_cursor) -{ - V_ASSERT(!p_cursor.hasSelection()); - p_cursor.insertBlock(); - return indentBlockAsBlock(p_cursor, false); -} - -bool VEditUtils::insertListMarkAsPreviousBlock(QTextCursor &p_cursor) -{ - bool ret = false; - QTextBlock block = p_cursor.block(); - QTextBlock preBlock = block.previous(); - if (!preBlock.isValid()) { - return false; - } - - QString text = preBlock.text(); - QRegExp regExp("^\\s*(-|\\d+\\.)\\s"); - int regIdx = regExp.indexIn(text); - if (regIdx != -1) { - ret = true; - V_ASSERT(regExp.captureCount() == 1); - QString markText = regExp.capturedTexts()[1]; - if (markText == "-") { - // Insert - in front. - p_cursor.insertText("- "); - } else { - // markText is like "123.". - V_ASSERT(markText.endsWith('.')); - bool ok = false; - int num = markText.left(markText.size() - 1).toInt(&ok, 10); - V_ASSERT(ok); - num++; - p_cursor.insertText(QString::number(num, 10) + ". "); - } - } - - return ret; - -} - -bool VEditUtils::indentBlockAsBlock(QTextCursor &p_cursor, bool p_next) -{ - QTextBlock block = p_cursor.block(); - QTextBlock refBlock = p_next ? block.next() : block.previous(); - return indentBlockAsBlock(p_cursor, refBlock); -} - -bool VEditUtils::indentBlockAsBlock(QTextCursor &p_cursor, const QTextBlock &p_refBlock) -{ - if (!p_refBlock.isValid()) { - return false; - } - - Q_ASSERT(!p_cursor.hasSelection()); - - bool changed = false; - QString leadingSpaces = fetchIndentSpaces(p_refBlock); - - moveCursorFirstNonSpaceCharacter(p_cursor, QTextCursor::MoveAnchor); - if (!p_cursor.atBlockStart()) { - p_cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); - p_cursor.removeSelectedText(); - changed = true; - } - - if (!leadingSpaces.isEmpty()) { - p_cursor.insertText(leadingSpaces); - changed = true; - } - - return changed; -} - -// Use another QTextCursor to remain the selection. -void VEditUtils::indentSelectedBlocksAsBlock(const QTextCursor &p_cursor, bool p_next) -{ - int nrBlocks = 1; - int start = p_cursor.selectionStart(); - int end = p_cursor.selectionEnd(); - - QTextDocument *doc = p_cursor.document(); - QTextBlock sBlock = doc->findBlock(start); - QTextBlock refBlock; - if (!p_next) { - refBlock = sBlock.previous(); - } - - if (start != end) { - QTextBlock eBlock = doc->findBlock(end); - nrBlocks = eBlock.blockNumber() - sBlock.blockNumber() + 1; - - if (p_next) { - refBlock = eBlock.next(); - } - } else { - refBlock = sBlock.next(); - } - - QTextCursor bCursor(sBlock); - bCursor.beginEditBlock(); - for (int i = 0; i < nrBlocks; ++i) { - indentBlockAsBlock(bCursor, refBlock); - - bCursor.movePosition(QTextCursor::NextBlock); - } - - bCursor.endEditBlock(); -} - -bool VEditUtils::hasSameIndent(const QTextBlock &p_blocka, const QTextBlock &p_blockb) -{ - int nonSpaceIdxa = 0; - int nonSpaceIdxb = 0; - - QString texta = p_blocka.text(); - for (int i = 0; i < texta.size(); ++i) { - if (!texta[i].isSpace()) { - nonSpaceIdxa = i; - break; - } - } - - QString textb = p_blockb.text(); - for (int i = 0; i < textb.size(); ++i) { - if (!textb[i].isSpace()) { - nonSpaceIdxb = i; - break; - } else if (i >= nonSpaceIdxa || texta[i] != textb[i]) { - return false; - } - } - - return nonSpaceIdxa == nonSpaceIdxb; -} - -void VEditUtils::moveCursorFirstNonSpaceCharacter(QTextCursor &p_cursor, - QTextCursor::MoveMode p_mode) -{ - QTextBlock block = p_cursor.block(); - QString text = block.text(); - int idx = 0; - for (; idx < text.size(); ++idx) { - if (text[idx].isSpace()) { - continue; - } else { - break; - } - } - - p_cursor.setPosition(block.position() + idx, p_mode); -} - -void VEditUtils::removeObjectReplacementCharacter(QString &p_text) -{ - QRegExp orcBlockExp(VUtils::c_previewImageBlockRegExp); - p_text.remove(orcBlockExp); - p_text.remove(QChar::ObjectReplacementCharacter); -} - -QString VEditUtils::selectedText(const QTextCursor &p_cursor) -{ - QString text = p_cursor.selectedText(); - text.replace(QChar::ParagraphSeparator, '\n'); - return text; -} - -// Use another QTextCursor to remain the selection. -void VEditUtils::indentSelectedBlocks(const QTextCursor &p_cursor, - const QString &p_indentationText, - bool p_isIndent) -{ - int nrBlocks = 1; - int start = p_cursor.selectionStart(); - int end = p_cursor.selectionEnd(); - - QTextDocument *doc = p_cursor.document(); - QTextBlock sBlock = doc->findBlock(start); - if (start != end) { - QTextBlock eBlock = doc->findBlock(end); - nrBlocks = eBlock.blockNumber() - sBlock.blockNumber() + 1; - } - - QTextCursor bCursor(sBlock); - bCursor.beginEditBlock(); - for (int i = 0; i < nrBlocks; ++i) { - if (p_isIndent) { - indentBlock(bCursor, p_indentationText); - } else { - unindentBlock(bCursor, p_indentationText); - } - - bCursor.movePosition(QTextCursor::NextBlock); - } - - bCursor.endEditBlock(); -} - -void VEditUtils::indentBlock(QTextCursor &p_cursor, - const QString &p_indentationText, - bool p_skipEmpty) -{ - QTextBlock block = p_cursor.block(); - if (block.length() > 1 || !p_skipEmpty) { - p_cursor.movePosition(QTextCursor::StartOfBlock); - p_cursor.insertText(p_indentationText); - } -} - -void VEditUtils::unindentBlock(QTextCursor &p_cursor, - const QString &p_indentationText) -{ - QTextBlock block = p_cursor.block(); - QString text = block.text(); - if (text.isEmpty()) { - return; - } - - p_cursor.movePosition(QTextCursor::StartOfBlock); - if (text[0] == '\t') { - p_cursor.deleteChar(); - } else if (text[0].isSpace()) { - int width = p_indentationText.size(); - for (int i = 0; i < width; ++i) { - if (text[i] == ' ') { - p_cursor.deleteChar(); - } else { - break; - } - } - } -} - -bool VEditUtils::findTargetWithinBlock(QTextCursor &p_cursor, - QTextCursor::MoveMode p_mode, - QChar p_target, - bool p_forward, - bool p_inclusive, - bool p_leftSideOfCursor, - int p_repeat) -{ - if (p_repeat < 1) { - return false; - } - - QTextBlock block = p_cursor.block(); - QString text = block.text(); - int pib = p_cursor.positionInBlock(); - int delta = p_forward ? 1 : -1; - - // The index to start searching. - int idx = pib + (p_inclusive ? delta : 2 * delta); - if (p_leftSideOfCursor) { - --idx; - } - - for (; idx < text.size() && idx >= 0; idx += delta) { - if (text[idx] == p_target) { - if (--p_repeat == 0) { - break; - } - } - } - - if (idx < 0 || idx >= text.size() || p_repeat > 0) { - return false; - } - - // text[idx] is the target character. - if ((p_forward && p_inclusive && p_mode == QTextCursor::KeepAnchor) - || (!p_forward && !p_inclusive)) { - ++idx; - } else if (p_forward && !p_inclusive && p_mode == QTextCursor::MoveAnchor) { - --idx; - } - - p_cursor.setPosition(block.position() + idx, p_mode); - return true; -} - -int VEditUtils::findTargetsWithinBlock(QTextCursor &p_cursor, - const QList &p_targets, - bool p_forward, - bool p_leftSideOfCursor, - bool p_inclusive) -{ - if (p_targets.isEmpty()) { - return -1; - } - - int targetIdx = -1; - QTextBlock block = p_cursor.block(); - QString text = block.text(); - int pib = p_cursor.positionInBlock(); - int delta = p_forward ? 1 : -1; - - // The index to start searching. - int idx = pib + (p_inclusive ? delta : 2 * delta); - if (p_leftSideOfCursor) { - --idx; - } - - for (; idx < text.size() && idx >= 0; idx += delta) { - int index = p_targets.indexOf(text[idx]); - if (index != -1) { - targetIdx = index; - break; - } - } - - if (idx < 0 || idx >= text.size()) { - return -1; - } - - // text[idx] is the target character. - if (p_forward && !p_inclusive) { - --idx; - } - - p_cursor.setPosition(block.position() + idx); - return targetIdx; -} - - -int VEditUtils::selectedBlockCount(const QTextCursor &p_cursor) -{ - if (!p_cursor.hasSelection()) { - return 0; - } - - QTextDocument *doc = p_cursor.document(); - int sbNum = doc->findBlock(p_cursor.selectionStart()).blockNumber(); - int ebNum = doc->findBlock(p_cursor.selectionEnd()).blockNumber(); - - return ebNum - sbNum + 1; -} - -void VEditUtils::scrollBlockInPage(QTextEdit *p_edit, - int p_blockNum, - int p_dest) -{ - QTextDocument *doc = p_edit->document(); - QTextCursor cursor = p_edit->textCursor(); - if (p_blockNum >= doc->blockCount()) { - p_blockNum = doc->blockCount() - 1; - } - - QTextBlock block = doc->findBlockByNumber(p_blockNum); - - int pib = cursor.positionInBlock(); - if (cursor.block().blockNumber() != p_blockNum) { - // Move the cursor to the block. - if (pib >= block.length()) { - pib = block.length() - 1; - } - - cursor.setPosition(block.position() + pib); - p_edit->setTextCursor(cursor); - } - - // Scroll to let current cursor locate in proper position. - p_edit->ensureCursorVisible(); - QScrollBar *vsbar = p_edit->verticalScrollBar(); - - if (!vsbar || !vsbar->isVisible()) { - // No vertical scrollbar. No need to scroll. - return; - } - - QRect rect = p_edit->cursorRect(); - int height = p_edit->rect().height(); - QScrollBar *sbar = p_edit->horizontalScrollBar(); - if (sbar && sbar->isVisible()) { - height -= sbar->height(); - } - - switch (p_dest) { - case 0: - { - // Top. - while (rect.y() > 0 && vsbar->value() < vsbar->maximum()) { - vsbar->setValue(vsbar->value() + vsbar->singleStep()); - rect = p_edit->cursorRect(); - } - - break; - } - - case 1: - { - // Center. - height = qMax(height / 2, 1); - if (rect.y() > height) { - while (rect.y() > height && vsbar->value() < vsbar->maximum()) { - vsbar->setValue(vsbar->value() + vsbar->singleStep()); - rect = p_edit->cursorRect(); - } - } else if (rect.y() < height) { - while (rect.y() < height && vsbar->value() > vsbar->minimum()) { - vsbar->setValue(vsbar->value() - vsbar->singleStep()); - rect = p_edit->cursorRect(); - } - } - - break; - } - - case 2: - // Bottom. - while (rect.y() < height && vsbar->value() > vsbar->minimum()) { - vsbar->setValue(vsbar->value() - vsbar->singleStep()); - rect = p_edit->cursorRect(); - } - - break; - - default: - break; - } - - p_edit->ensureCursorVisible(); -} - -void VEditUtils::scrollBlockInPage(QPlainTextEdit *p_edit, - int p_blockNum, - int p_dest) -{ - QTextDocument *doc = p_edit->document(); - QTextCursor cursor = p_edit->textCursor(); - if (p_blockNum >= doc->blockCount()) { - p_blockNum = doc->blockCount() - 1; - } - - QTextBlock block = doc->findBlockByNumber(p_blockNum); - - int pib = cursor.positionInBlock(); - if (cursor.block().blockNumber() != p_blockNum) { - // Move the cursor to the block. - if (pib >= block.length()) { - pib = block.length() - 1; - } - - cursor.setPosition(block.position() + pib); - p_edit->setTextCursor(cursor); - } - - // Scroll to let current cursor locate in proper position. - p_edit->ensureCursorVisible(); - QScrollBar *vsbar = p_edit->verticalScrollBar(); - - if (!vsbar || !vsbar->isVisible()) { - // No vertical scrollbar. No need to scroll. - return; - } - - QRect rect = p_edit->cursorRect(); - int height = p_edit->rect().height(); - QScrollBar *sbar = p_edit->horizontalScrollBar(); - if (sbar && sbar->isVisible()) { - height -= sbar->height(); - } - - switch (p_dest) { - case 0: - { - // Top. - while (rect.y() > 0 && vsbar->value() < vsbar->maximum()) { - vsbar->setValue(vsbar->value() + vsbar->singleStep()); - rect = p_edit->cursorRect(); - } - - break; - } - - case 1: - { - // Center. - height = qMax(height / 2, 1); - if (rect.y() > height) { - while (rect.y() > height && vsbar->value() < vsbar->maximum()) { - vsbar->setValue(vsbar->value() + vsbar->singleStep()); - rect = p_edit->cursorRect(); - } - } else if (rect.y() < height) { - while (rect.y() < height && vsbar->value() > vsbar->minimum()) { - vsbar->setValue(vsbar->value() - vsbar->singleStep()); - rect = p_edit->cursorRect(); - } - } - - break; - } - - case 2: - // Bottom. - while (rect.y() < height && vsbar->value() > vsbar->minimum()) { - vsbar->setValue(vsbar->value() - vsbar->singleStep()); - rect = p_edit->cursorRect(); - } - - break; - - default: - break; - } - - p_edit->ensureCursorVisible(); -} - -bool VEditUtils::isListBlock(const QTextBlock &p_block, int *p_seq) -{ - QString text = p_block.text(); - QRegExp regExp("^\\s*(-|\\d+\\.)\\s"); - - if (p_seq) { - *p_seq = -1; - } - - int regIdx = regExp.indexIn(text); - if (regIdx == -1) { - return false; - } - - V_ASSERT(regExp.captureCount() == 1); - QString markText = regExp.capturedTexts()[1]; - if (markText != "-") { - V_ASSERT(markText.endsWith('.')); - bool ok = false; - int num = markText.left(markText.size() - 1).toInt(&ok, 10); - V_ASSERT(ok); - if (p_seq) { - *p_seq = num; - } - } - - return true; -} - -bool VEditUtils::isSpaceToBlockStart(const QTextBlock &p_block, int p_posInBlock) -{ - if (p_posInBlock <= 0) { - return true; - } - - QString text = p_block.text(); - V_ASSERT(text.size() >= p_posInBlock); - return text.left(p_posInBlock).trimmed().isEmpty(); -} - -bool VEditUtils::isSpaceBlock(const QTextBlock &p_block) -{ - return p_block.text().trimmed().isEmpty(); -} - -void VEditUtils::deleteIndentAndListMark(QTextCursor &p_cursor) -{ - V_ASSERT(!p_cursor.hasSelection()); - p_cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); - p_cursor.removeSelectedText(); -} - - -bool VEditUtils::selectPairTargetAround(QTextCursor &p_cursor, - QChar p_opening, - QChar p_closing, - bool p_inclusive, - bool p_crossBlock, - int p_repeat) -{ - Q_ASSERT(p_repeat >= 1); - - QTextDocument *doc = p_cursor.document(); - int pos = p_cursor.position(); - - // Search range [start, end]. - int start = 0; - int end = doc->characterCount() - 1; - if (!p_crossBlock) { - QTextBlock block = p_cursor.block(); - start = block.position(); - end = block.position() + block.length() - 1; - } - - if (start == end || pos > end) { - return false; - } - - Q_ASSERT(!doc->characterAt(pos).isNull()); - - bool found = false; - - // The number of un-paired symbols before we meet a target. - // For example, when we are searching the `(`, nrPair is the number of - // the un-paired `)` currently. - int nrPair = 0; - - // The absolute position of the found target. - // vnote|(vnote|)vnote - int opening = pos; - int closing = pos; - -round: - // "abc|"def", after `di"`, becomes "|"def" - // So we need to try closing first. - QChar ch = doc->characterAt(closing); - Q_ASSERT(!ch.isNull()); - if (ch == p_closing) { - // Try to find the opening. - nrPair = 1; - int i = opening; - if (opening == closing) { - --i; - } - - for (; i >= start; --i) { - ch = doc->characterAt(i); - Q_ASSERT(!ch.isNull()); - if (ch == p_opening) { - if (--nrPair == 0) { - break; - } - } else if (ch == p_closing) { - ++nrPair; - } - } - - if (i >= start) { - // Found the opening. Done. - opening = i; - found = true; - } - } - - ch = doc->characterAt(opening); - Q_ASSERT(!ch.isNull()); - if (!found && ch == p_opening) { - // Try to find the closing. - nrPair = 1; - int j = closing; - if (opening == closing) { - ++j; - } - - for (; j <= end; ++j) { - ch = doc->characterAt(j); - Q_ASSERT(!ch.isNull()); - if (ch == p_closing) { - if (--nrPair == 0) { - break; - } - } else if (ch == p_opening) { - ++nrPair; - } - } - - if (j <= end) { - // Foudnd the closing. Done. - closing = j; - found = true; - } - } - - if (!found - && doc->characterAt(opening) != p_opening - && doc->characterAt(closing) != p_closing) { - // Need to find both the opening and closing. - int i = opening - 1; - int j = closing + 1; - // Pretend that we have found one. - nrPair = 1; - for (; i >= start; --i) { - ch = doc->characterAt(i); - Q_ASSERT(!ch.isNull()); - if (ch == p_opening) { - if (--nrPair == 0) { - break; - } - } else if (ch == p_closing) { - ++nrPair; - } - } - - if (i >= start) { - opening = i; - // Continue to find the closing. - nrPair = 1; - for (; j <= end; ++j) { - ch = doc->characterAt(j); - Q_ASSERT(!ch.isNull()); - if (ch == p_closing) { - if (--nrPair == 0) { - break; - } - } else if (ch == p_opening) { - ++nrPair; - } - } - - if (j <= end) { - closing = j; - found = true; - } - } - } - - if (!found) { - return false; - } else if (--p_repeat) { - // Need to find more. - found = false; - --opening; - ++closing; - - if (opening < start && closing > end) { - return false; - } - - goto round; - } - - if (p_inclusive) { - ++closing; - } else { - ++opening; - } - - p_cursor.setPosition(opening, QTextCursor::MoveAnchor); - p_cursor.setPosition(closing, QTextCursor::KeepAnchor); - return true; -} - -int VEditUtils::findNextEmptyBlock(const QTextCursor &p_cursor, - bool p_forward, - int p_repeat) -{ - Q_ASSERT(p_repeat > 0); - int res = -1; - QTextBlock block = p_cursor.block(); - if (p_forward) { - block = block.next(); - } else { - block = block.previous(); - } - - while (block.isValid()) { - if (block.length() == 1) { - res = block.position(); - if (--p_repeat == 0) { - break; - } - } - - if (p_forward) { - block = block.next(); - } else { - block = block.previous(); - } - } - - return p_repeat > 0 ? -1 : res; -} - -bool VEditUtils::needToCancelAutoIndent(int p_autoIndentPos, const QTextCursor &p_cursor) -{ - // Cancel the auto indent/list if the pos is the same and cursor is at - // the end of a block. - QTextBlock block = p_cursor.block(); - if (p_cursor.position() == p_autoIndentPos - && !p_cursor.hasSelection() - && p_cursor.atBlockEnd()) { - if (isListBlock(block)) { - return true; - } else if (isSpaceToBlockStart(block, - p_cursor.positionInBlock())) { - return true; - } - } - - return false; -} - -void VEditUtils::insertTitleMark(QTextCursor &p_cursor, - const QTextBlock &p_block, - int p_level) -{ - if (!p_block.isValid()) { - return; - } - - Q_ASSERT(p_level >= 0 && p_level <= 6); - - bool needInsert = true; - - p_cursor.setPosition(p_block.position()); - - // Test if this block contains title marks. - QRegExp headerReg(VUtils::c_headerRegExp); - QString text = p_block.text(); - bool matched = headerReg.exactMatch(text); - if (matched) { - int level = headerReg.cap(1).length(); - if (level == p_level) { - needInsert = false; - } else { - // Remove the title mark. - int length = level; - if (p_level == 0) { - // Remove all the prefix. - QRegExp prefixReg(VUtils::c_headerPrefixRegExp); - bool preMatched = prefixReg.exactMatch(text); - Q_UNUSED(preMatched); - Q_ASSERT(preMatched); - length = prefixReg.cap(1).length(); - } - - p_cursor.movePosition(QTextCursor::NextCharacter, - QTextCursor::KeepAnchor, - length); - p_cursor.removeSelectedText(); - } - } - - // Insert titleMark + " " at the front of the block. - if (p_level > 0 && needInsert) { - // Remove the spaces at front. - // insertText() will remove the selection. - moveCursorFirstNonSpaceCharacter(p_cursor, QTextCursor::KeepAnchor); - - // Insert. - const QString titleMark(p_level, '#'); - p_cursor.insertText(titleMark + " "); - } - - // Go to the end of this block. - p_cursor.movePosition(QTextCursor::EndOfBlock); -} - -void VEditUtils::findCurrentWord(QTextCursor p_cursor, - int &p_start, - int &p_end) -{ - QString text = p_cursor.block().text(); - int pib = p_cursor.positionInBlock(); - - if (pib < text.size() && text[pib].isSpace()) { - p_start = p_end = p_cursor.position(); - return; - } - - p_cursor.movePosition(QTextCursor::StartOfWord); - p_start = p_cursor.position(); - p_cursor.movePosition(QTextCursor::EndOfWord); - p_end = p_cursor.position(); -} - -void VEditUtils::findCurrentWORD(const QTextCursor &p_cursor, - int &p_start, - int &p_end) -{ - QTextBlock block = p_cursor.block(); - QString text = block.text(); - int pib = p_cursor.positionInBlock(); - - if (pib < text.size() && text[pib].isSpace()) { - p_start = p_end = p_cursor.position(); - return; - } - - // Find the start. - p_start = 0; - for (int i = pib - 1; i >= 0; --i) { - if (text[i].isSpace()) { - p_start = i + 1; - break; - } - } - - // Find the end. - p_end = block.length() - 1; - for (int i = pib; i < text.size(); ++i) { - if (text[i].isSpace()) { - p_end = i; - break; - } - } - - p_start += block.position(); - p_end += block.position(); -} - -QString VEditUtils::fetchIndentSpaces(const QTextBlock &p_block) -{ - QString text = p_block.text(); - QRegExp regExp("(^\\s*)"); - regExp.indexIn(text); - Q_ASSERT(regExp.captureCount() == 1); - return regExp.capturedTexts()[1]; -} - -void VEditUtils::insertBlock(QTextCursor &p_cursor, - bool p_above) -{ - p_cursor.movePosition(p_above ? QTextCursor::StartOfBlock - : QTextCursor::EndOfBlock, - QTextCursor::MoveAnchor, - 1); - - p_cursor.insertBlock(); - - if (p_above) { - p_cursor.movePosition(QTextCursor::PreviousBlock, - QTextCursor::MoveAnchor, - 1); - } - - p_cursor.movePosition(QTextCursor::EndOfBlock); -} diff --git a/src/utils/veditutils.h b/src/utils/veditutils.h deleted file mode 100644 index 175bac85..00000000 --- a/src/utils/veditutils.h +++ /dev/null @@ -1,196 +0,0 @@ -#ifndef VEDITUTILS_H -#define VEDITUTILS_H - -#include -#include - -class QTextDocument; -class QTextEdit; -class QPlainTextEdit; - -// Utils for text edit. -class VEditUtils -{ -public: - // Remove the whole block @p_block. - // If @p_text is not NULL, return the deleted text here. - static void removeBlock(QTextBlock &p_block, QString *p_text = NULL); - - // Remove the whole block under @p_cursor. - // If @p_text is not NULL, return the deleted text here. - // Need to call setTextCursor() to make it take effect. - static void removeBlock(QTextCursor &p_cursor, QString *p_text = NULL); - - // Move @p_cursor to the first non-space character of current block. - // Need to call setTextCursor() to make it take effect. - static void moveCursorFirstNonSpaceCharacter(QTextCursor &p_cursor, - QTextCursor::MoveMode p_mode); - // Indent current block as next/previous block. - // Return true if some changes have been made. - // @p_cursor will be placed at the position after inserting leading spaces. - // @p_next: indent as next block or previous block. - static bool indentBlockAsBlock(QTextCursor &p_cursor, bool p_next); - - // Indent current block as @p_refBlock. - static bool indentBlockAsBlock(QTextCursor &p_cursor, const QTextBlock &p_refBlock); - - // Returns true if two blocks has the same indent. - static bool hasSameIndent(const QTextBlock &p_blocka, const QTextBlock &p_blockb); - - // Insert a new block at current position with the same indentation as - // current block. Should clear the selection before calling this. - // Returns true if non-empty indentation has been inserted. - // Need to call setTextCursor() to make it take effect. - static bool insertBlockWithIndent(QTextCursor &p_cursor); - - // Fetch the list mark of previous block, and insert it at current position. - // Returns true if list mark has been inserted. - // Need to call setTextCursor() to make it take effect. - static bool insertListMarkAsPreviousBlock(QTextCursor &p_cursor); - - // Remove ObjectReplaceCharacter in p_text. - // If the ObjectReplaceCharacter is in a block with only other spaces, remove the - // whole block. - static void removeObjectReplacementCharacter(QString &p_text); - - // p_cursor.selectedText() will use U+2029 (QChar::ParagraphSeparator) - // instead of \n for a new line. - // This function will translate it to \n. - static QString selectedText(const QTextCursor &p_cursor); - - // Indent selected blocks. If no selection, indent current block. - // Cursor position and selection is not changed. - // @p_isIndent: whether it is indentation or unindentation. - static void indentSelectedBlocks(const QTextCursor &p_cursor, - const QString &p_indentationText, - bool p_isIndent); - - // Indent seleced block as next/previous block. - // Cursor position and selection is not changed. - // Return true if some changes have been made. - // @p_next: indent as next block or previous block. - static void indentSelectedBlocksAsBlock(const QTextCursor &p_cursor, bool p_next); - - // Indent current block. - // @p_skipEmpty: skip empty block. - static void indentBlock(QTextCursor &p_cursor, - const QString &p_indentationText, - bool p_skipEmpty = true); - - static void unindentBlock(QTextCursor &p_cursor, - const QString &p_indentationText); - - // Find @p_repeat th occurence of a char within a block. - // Returns true if target is found. - // Please pay attention to the one-step-forward/backward in KeepAnchor mode - // and exclusive case. - static bool findTargetWithinBlock(QTextCursor &p_cursor, - QTextCursor::MoveMode p_mode, - QChar p_target, - bool p_forward, - bool p_inclusive, - bool p_leftSideOfCursor, - int p_repeat); - - // Find th first occurence of a char in @p_targets within a block. - // Returns the index of the found char in @p_targets if found. - // Returns -1 if none of the @p_targets is found. - // Different from findTargetWithinBlock(), will not modify the ucrsor position - // even in KeepAnchor mode. - static int findTargetsWithinBlock(QTextCursor &p_cursor, - const QList &p_targets, - bool p_forward, - bool p_leftSideOfCursor, - bool p_inclusive); - - // Find a pair target (@p_opening, @p_closing) containing current cursor and - // select the range between them. - // Need to call setTextCursor() to make it take effect. - // Returns true if target is found. - static bool selectPairTargetAround(QTextCursor &p_cursor, - QChar p_opening, - QChar p_closing, - bool p_inclusive, - bool p_crossBlock, - int p_repeat); - - // Get the count of blocks selected. - static int selectedBlockCount(const QTextCursor &p_cursor); - - // Scroll block @p_blockNum into the visual window. - // @p_dest is the position of the window: 0 for top, 1 for center, 2 for bottom. - // @p_blockNum is based on 0. - // Will set the cursor to the block. - static void scrollBlockInPage(QTextEdit *p_edit, - int p_blockNum, - int p_dest); - - // Scroll block @p_blockNum into the visual window. - // @p_dest is the position of the window: 0 for top, 1 for center, 2 for bottom. - // @p_blockNum is based on 0. - // Will set the cursor to the block. - static void scrollBlockInPage(QPlainTextEdit *p_edit, - int p_blockNum, - int p_dest); - - // Check if @p_block is a auto list block. - // @p_seq will be the seq number of the ordered list, or -1. - // Returns true if it is an auto list block. - static bool isListBlock(const QTextBlock &p_block, int *p_seq = NULL); - - // If the start of @p_block to postition @p_posInBlock are spaces. - static bool isSpaceToBlockStart(const QTextBlock &p_block, int p_posInBlock); - - // If block @p_block only contains spaces. - static bool isSpaceBlock(const QTextBlock &p_block); - - // @p_cursor is positioned right after auto indetn and auto list. - // Need to call setTextCursor() to make it take effect. - static void deleteIndentAndListMark(QTextCursor &p_cursor); - - // Find next @p_repeat empty block. - // Returns the position of that block if found. Otherwise, returns -1. - static int findNextEmptyBlock(const QTextCursor &p_cursor, - bool p_forward, - int p_repeat); - - // Check if we need to cancel auto indent. - // @p_autoIndentPos: the position of the cursor after auto indent. - static bool needToCancelAutoIndent(int p_autoIndentPos, - const QTextCursor &p_cursor); - - // Insert title Mark at level @p_level in front of block @p_block - // If there already exists title marks, remove it first. - // Move cursor at the end of the block after insertion. - // If @p_level is 0, remove the title mark. - static void insertTitleMark(QTextCursor &p_cursor, - const QTextBlock &p_block, - int p_level); - - // Find the start and end of the word @p_cursor locates in (within a single block). - // @p_start and @p_end will be the global position of the start and end of the word. - // @p_start will equals to @p_end if @p_cursor is a space. - static void findCurrentWord(QTextCursor p_cursor, - int &p_start, - int &p_end); - - // Find the start and end of the WORD @p_cursor locates in (within a single block). - // @p_start and @p_end will be the global position of the start and end of the WORD. - // @p_start will equals to @p_end if @p_cursor is a space. - static void findCurrentWORD(const QTextCursor &p_cursor, - int &p_start, - int &p_end); - - // Return the leading spaces of @p_block. - static QString fetchIndentSpaces(const QTextBlock &p_block); - - // Insert a block above/below current block. Move the cursor to the start of - // the new block after insertion. - static void insertBlock(QTextCursor &p_cursor, - bool p_above); - -private: - VEditUtils() {} -}; - -#endif // VEDITUTILS_H diff --git a/src/utils/viconutils.cpp b/src/utils/viconutils.cpp deleted file mode 100644 index aeb8dfc9..00000000 --- a/src/utils/viconutils.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "viconutils.h" - -#include -#include -#include -#include -#include - -#include "vutils.h" - -VIconUtils::VIconUtils() -{ - -} - -QIcon VIconUtils::icon(const QString &p_file, const QString &p_fg, bool p_addDisabled) -{ - QFileInfo fi(p_file); - bool isSvg = fi.suffix().toLower() == "svg"; - if (p_fg.isEmpty() || !isSvg) { - return QIcon(p_file); - } - - QString content = VUtils::readFileFromDisk(p_file); - Q_ASSERT(!content.isEmpty()); - // Must have a # to avoid fill="none". - QRegExp reg("(\\s|\")(fill|stroke)(:|(=\"))#[^#\"\\s]+"); - if (content.indexOf(reg) == -1) { - return QIcon(p_file); - } - - content.replace(reg, QString("\\1\\2\\3%1").arg(p_fg)); - QByteArray data = content.toLocal8Bit(); - QPixmap pixmap; - pixmap.loadFromData(data, "svg"); - - // Disabled. - QPixmap disabledPixmap; - if (p_addDisabled) { - content.replace(reg, QString("\\1\\2\\3%1").arg(g_palette->color("icon_disabled_fg"))); - data = content.toLocal8Bit(); - disabledPixmap.loadFromData(data, "svg"); - } - - QIcon icon; - icon.addPixmap(pixmap, QIcon::Normal); - if (p_addDisabled) { - icon.addPixmap(disabledPixmap, QIcon::Disabled); - } - - return icon; -} diff --git a/src/utils/viconutils.h b/src/utils/viconutils.h deleted file mode 100644 index 8a7422f7..00000000 --- a/src/utils/viconutils.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef VICONUTILS_H -#define VICONUTILS_H - -#include -#include - -#include "vpalette.h" - -extern VPalette *g_palette; - - -class VIconUtils -{ -public: - // Get an icon from @p_file file. May change the foreground of the icon. - static QIcon icon(const QString &p_file, - const QString &p_fg = QString(), - bool p_addDisabled = true); - - static QIcon toolButtonIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("toolbutton_icon_fg")); - } - - static QIcon toolButtonDangerIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("toolbutton_icon_danger_fg")); - } - - static QIcon menuIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("menu_icon_fg")); - } - - static QIcon menuDangerIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("menu_icon_danger_fg")); - } - - static QIcon toolBoxIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("toolbox_icon_fg")); - } - - static QIcon toolBoxActiveIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("toolbox_icon_active_fg")); - } - - static QIcon comboBoxIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("combobox_item_icon_fg")); - } - - static QIcon treeViewIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("treeview_item_icon_fg")); - } - - static QIcon tabBarIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("tabbar_icon_fg")); - } - - static QIcon tabBarSpecialIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("tabbar_icon_special_fg")); - } - - static QIcon editWindowCornerIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("editwindow_corner_icon_fg")); - } - - static QIcon editWindowCornerInactiveIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("editwindow_corner_icon_inactive_fg")); - } - - static QIcon titleIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("title_icon_fg")); - } - - static QIcon buttonIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("button_icon_fg")); - } - - static QIcon buttonDangerIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("button_icon_danger_fg")); - } - -private: - VIconUtils(); -}; - -#endif // VICONUTILS_H diff --git a/src/utils/vimnavigationforwidget.cpp b/src/utils/vimnavigationforwidget.cpp deleted file mode 100644 index 34df417e..00000000 --- a/src/utils/vimnavigationforwidget.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "vimnavigationforwidget.h" - -#include -#include -#include -#include - -#include "vutils.h" - -VimNavigationForWidget::VimNavigationForWidget() -{ -} - -bool VimNavigationForWidget::injectKeyPressEventForVim(QWidget *p_widget, - QKeyEvent *p_event, - QWidget *p_escWidget) -{ - Q_ASSERT(p_widget); - - bool ret = false; - int key = p_event->key(); - int modifiers = p_event->modifiers(); - if (!p_escWidget) { - p_escWidget = p_widget; - } - - switch (key) { - case Qt::Key_BracketLeft: - { - if (VUtils::isControlModifierForVim(modifiers)) { - QKeyEvent *escEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Escape, - Qt::NoModifier); - QCoreApplication::postEvent(p_escWidget, escEvent); - ret = true; - } - - break; - } - - case Qt::Key_J: - { - if (VUtils::isControlModifierForVim(modifiers)) { - QKeyEvent *downEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Down, - Qt::NoModifier); - QCoreApplication::postEvent(p_widget, downEvent); - ret = true; - } - - break; - } - - case Qt::Key_K: - { - if (VUtils::isControlModifierForVim(modifiers)) { - QKeyEvent *upEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Up, - Qt::NoModifier); - QCoreApplication::postEvent(p_widget, upEvent); - ret = true; - } - - break; - } - - default: - break; - } - - return ret; -} diff --git a/src/utils/vimnavigationforwidget.h b/src/utils/vimnavigationforwidget.h deleted file mode 100644 index 86028e60..00000000 --- a/src/utils/vimnavigationforwidget.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef VIMNAVIGATIONFORWIDGET_H -#define VIMNAVIGATIONFORWIDGET_H - -class QWidget; -class QKeyEvent; - - -// Provide simple Vim mode navigation for widgets. -class VimNavigationForWidget -{ -public: - // Try to handle @p_event and inject proper event instead if it triggers - // Vim operation. - // Return true if @p_event is handled properly. - // @p_escWidget: the widget to accept the ESC event. - static bool injectKeyPressEventForVim(QWidget *p_widget, - QKeyEvent *p_event, - QWidget *p_escWidget = nullptr); - -private: - VimNavigationForWidget(); -}; - -#endif // VIMNAVIGATIONFORWIDGET_H diff --git a/src/utils/vmetawordmanager.cpp b/src/utils/vmetawordmanager.cpp deleted file mode 100644 index eb36100b..00000000 --- a/src/utils/vmetawordmanager.cpp +++ /dev/null @@ -1,659 +0,0 @@ -#include "vmetawordmanager.h" - -#include -#include -#include -#include -#include - -#include "vconfigmanager.h" -#include "vmainwindow.h" - -extern VConfigManager *g_config; - -extern VMainWindow *g_mainWin; - - -// Used as the function template for some date/time related meta words. -static QString formattedDateTime(const VMetaWord *p_metaWord, - const QString &p_format) -{ - return p_metaWord->getManager()->getDateTime().toString(p_format); -} - -static QString allMetaWordsInfo(const VMetaWord *p_metaWord) -{ - QString msg = QObject::tr("All magic words:"); - - const VMetaWordManager *mgr = p_metaWord->getManager(); - QList keys = mgr->getAllMetaWords().keys(); - keys.sort(Qt::CaseInsensitive); - - for (auto const & key : keys) { - const VMetaWord *word = mgr->findMetaWord(key); - Q_ASSERT(word); - msg += QString("\n%1:\t%2").arg(word->getWord()).arg(word->getDefinition()); - } - - QWidget *focusWid = QApplication::focusWidget(); - if (focusWid) { - QPoint pos = focusWid->mapToGlobal(QPoint(0, focusWid->height())); - QToolTip::showText(pos, msg, focusWid); - } - - // Just return the same word. - return QString("%1help%1").arg(VMetaWordManager::c_delimiter); -} - -const QChar VMetaWordManager::c_delimiter = '%'; - -VMetaWordManager::VMetaWordManager(QObject *p_parent) - : QObject(p_parent) -{ -} - -void VMetaWordManager::init() -{ - using namespace std::placeholders; - - // %d%. - addMetaWord(MetaWordType::FunctionBased, - "d", - tr("the day as number without a leading zero (`1` to `31`)"), - std::bind(formattedDateTime, _1, "d")); - - // %dd%. - addMetaWord(MetaWordType::FunctionBased, - "dd", - tr("the day as number with a leading zero (`01` to `31`)"), - std::bind(formattedDateTime, _1, "dd")); - - // %ddd%. - addMetaWord(MetaWordType::FunctionBased, - "ddd", - tr("the abbreviated localized day name (e.g. `Mon` to `Sun`)"), - std::bind(formattedDateTime, _1, "ddd")); - - // %dddd%. - addMetaWord(MetaWordType::FunctionBased, - "dddd", - tr("the long localized day name (e.g. `Monday` to `Sunday`)"), - std::bind(formattedDateTime, _1, "dddd")); - - // %M%. - addMetaWord(MetaWordType::FunctionBased, - "M", - tr("the month as number without a leading zero (`1` to `12`)"), - std::bind(formattedDateTime, _1, "M")); - - // %MM%. - addMetaWord(MetaWordType::FunctionBased, - "MM", - tr("the month as number with a leading zero (`01` to `12`)"), - std::bind(formattedDateTime, _1, "MM")); - - // %MMM%. - addMetaWord(MetaWordType::FunctionBased, - "MMM", - tr("the abbreviated localized month name (e.g. `Jan` to `Dec`)"), - std::bind(formattedDateTime, _1, "MMM")); - - // %MMMM%. - addMetaWord(MetaWordType::FunctionBased, - "MMMM", - tr("the long localized month name (e.g. `January` to `December`)"), - std::bind(formattedDateTime, _1, "MMMM")); - - // %yy%. - addMetaWord(MetaWordType::FunctionBased, - "yy", - tr("the year as two digit number (`00` to `99`)"), - std::bind(formattedDateTime, _1, "yy")); - - // %yyyy%. - addMetaWord(MetaWordType::FunctionBased, - "yyyy", - tr("the year as four digit number"), - std::bind(formattedDateTime, _1, "yyyy")); - - // %h%. - addMetaWord(MetaWordType::FunctionBased, - "h", - tr("the hour without a leading zero (`0` to `23` or `1` to `12` if AM/PM display)"), - std::bind(formattedDateTime, _1, "h")); - - // %hh%. - addMetaWord(MetaWordType::FunctionBased, - "hh", - tr("the hour with a leading zero (`00` to `23` or `01` to `12` if AM/PM display)"), - std::bind(formattedDateTime, _1, "hh")); - - // %H%. - addMetaWord(MetaWordType::FunctionBased, - "H", - tr("the hour without a leading zero (`0` to `23` even with AM/PM display)"), - std::bind(formattedDateTime, _1, "H")); - - // %HH%. - addMetaWord(MetaWordType::FunctionBased, - "HH", - tr("the hour with a leading zero (`00` to `23` even with AM/PM display)"), - std::bind(formattedDateTime, _1, "HH")); - - // %m%. - addMetaWord(MetaWordType::FunctionBased, - "m", - tr("the minute without a leading zero (`0` to `59`)"), - std::bind(formattedDateTime, _1, "m")); - - // %mm%. - addMetaWord(MetaWordType::FunctionBased, - "mm", - tr("the minute with a leading zero (`00` to `59`)"), - std::bind(formattedDateTime, _1, "mm")); - - // %s%. - addMetaWord(MetaWordType::FunctionBased, - "s", - tr("the second without a leading zero (`0` to `59`)"), - std::bind(formattedDateTime, _1, "s")); - - // %ss%. - addMetaWord(MetaWordType::FunctionBased, - "ss", - tr("the second with a leading zero (`00` to `59`)"), - std::bind(formattedDateTime, _1, "ss")); - - // %z%. - addMetaWord(MetaWordType::FunctionBased, - "z", - tr("the milliseconds without leading zeroes (`0` to `999`)"), - std::bind(formattedDateTime, _1, "z")); - - // %zzz%. - addMetaWord(MetaWordType::FunctionBased, - "zzz", - tr("the milliseconds with leading zeroes (`000` to `999`)"), - std::bind(formattedDateTime, _1, "zzz")); - - // %AP%. - addMetaWord(MetaWordType::FunctionBased, - "AP", - tr("use AM/PM display (`AM` or `PM`)"), - std::bind(formattedDateTime, _1, "AP")); - - // %A%. - addMetaWord(MetaWordType::FunctionBased, - "A", - tr("use AM/PM display (`AM` or `PM`)"), - std::bind(formattedDateTime, _1, "A")); - - // %ap%. - addMetaWord(MetaWordType::FunctionBased, - "ap", - tr("use am/pm display (`am` or `pm`)"), - std::bind(formattedDateTime, _1, "ap")); - - // %a%. - addMetaWord(MetaWordType::FunctionBased, - "a", - tr("use am/pm display (`am` or `pm`)"), - std::bind(formattedDateTime, _1, "a")); - - // %t%. - addMetaWord(MetaWordType::FunctionBased, - "t", - tr("the timezone (e.g. `CEST`)"), - std::bind(formattedDateTime, _1, "t")); - - // %random%. - addMetaWord(MetaWordType::FunctionBased, - "random", - tr("a random number"), - [](const VMetaWord *) { - return QString::number(qrand()); - }); - - // %random_d%. - addMetaWord(MetaWordType::Dynamic, - "random_d", - tr("dynamic version of `random`"), - [](const VMetaWord *) { - return QString::number(qrand()); - }); - - // %date%. - addMetaWord(MetaWordType::Compound, - "date", - QString("%1yyyy%1-%1MM%1-%1dd%1").arg(c_delimiter)); - - // %da%. - addMetaWord(MetaWordType::Compound, - "da", - QString("%1yyyy%1%1MM%1%1dd%1").arg(c_delimiter)); - - // %time%. - addMetaWord(MetaWordType::Compound, - "time", - QString("%1hh%1:%1mm%1:%1ss%1").arg(c_delimiter)); - - // %datetime%. - addMetaWord(MetaWordType::Compound, - "datetime", - QString("%1date%1 %1time%1").arg(c_delimiter)); - - // %dt%. - addMetaWord(MetaWordType::Compound, - "dt", - QString("%1da%1-%1time%1").arg(c_delimiter)); - - // %note%. - addMetaWord(MetaWordType::FunctionBased, - "note", - tr("name of current note"), - [](const VMetaWord *) { - const VFile *file = g_mainWin->getCurrentFile(); - if (file) { - return file->getName(); - } - - return QString(); - }); - - // %no%. - addMetaWord(MetaWordType::FunctionBased, - "no", - tr("complete base name of current note"), - [](const VMetaWord *) { - const VFile *file = g_mainWin->getCurrentFile(); - if (file) { - return QFileInfo(file->getName()).completeBaseName(); - } - - return QString(); - }); - - // Custom meta words. - initCustomMetaWords(); - - // %help% to print all metaword info. - addMetaWord(MetaWordType::FunctionBased, - "help", - tr("information about all defined magic words"), - allMetaWordsInfo); -} - -void VMetaWordManager::initCustomMetaWords() -{ - QVector words = g_config->getCustomMagicWords(); - for (auto const & item : words) { - addMetaWord(MetaWordType::Compound, - item.m_name, - item.m_definition); - } -} - -QString VMetaWordManager::evaluate(const QString &p_text, - const QHash &p_overriddenWords) const -{ - if (p_text.isEmpty()) { - return p_text; - } - - // Update datetime for later parse. - const_cast(this)->m_dateTime = QDateTime::currentDateTime(); - - // Update overriden table. - const_cast(this)->m_overriddenWords = p_overriddenWords; - - // Treat the text as a Compound meta word. - const QString tmpWord("vnote_tmp_metaword"); - Q_ASSERT(!contains(tmpWord)); - VMetaWord metaWord(this, - MetaWordType::Compound, - tmpWord, - p_text, - nullptr, - true); - - QString val; - if (metaWord.isValid()) { - val = metaWord.evaluate(); - } else { - val = p_text; - } - - const_cast(this)->m_overriddenWords.clear(); - - return val; -} - -bool VMetaWordManager::contains(const QString &p_word) const -{ - return m_metaWords.contains(p_word); -} - -const VMetaWord *VMetaWordManager::findMetaWord(const QString &p_word) const -{ - auto it = m_metaWords.find(p_word); - if (it != m_metaWords.end()) { - return &it.value(); - } - - return NULL; -} - -void VMetaWordManager::addMetaWord(MetaWordType p_type, - const QString &p_word, - const QString &p_definition, - MetaWordFunc p_function) -{ - if (p_word.isEmpty() || contains(p_word)) { - return; - } - - VMetaWord metaWord(this, - p_type, - p_word, - p_definition, - p_function); - - if (metaWord.isValid()) { - m_metaWords.insert(p_word, metaWord); - qDebug() << QString("MetaWord %1%2%1[%3] added") - .arg(c_delimiter).arg(p_word).arg(p_definition); - } -} - -bool VMetaWordManager::findOverriddenValue(const QString &p_word, - QString &p_value) const -{ - auto it = m_overriddenWords.find(p_word); - if (it != m_overriddenWords.end()) { - p_value = it.value(); - return true; - } - - return false; -} - -VMetaWord::VMetaWord(const VMetaWordManager *p_manager, - MetaWordType p_type, - const QString &p_word, - const QString &p_definition, - MetaWordFunc p_function, - bool p_allowAllSpaces) - : m_manager(p_manager), - m_type(p_type), - m_word(p_word), - m_definition(p_definition), - m_valid(false) -{ - m_function = p_function; - - if (checkType(MetaWordType::Simple) - || checkType(MetaWordType::Compound)) { - Q_ASSERT(!m_function); - } else { - Q_ASSERT(m_function); - } - - checkAndParseDefinition(p_allowAllSpaces); -} - -bool VMetaWord::checkType(MetaWordType p_type) -{ - return m_type == p_type; -} - -void VMetaWord::checkAndParseDefinition(bool p_allowAllSpaces) -{ - if (m_word.contains(VMetaWordManager::c_delimiter)) { - m_valid = false; - return; - } - - m_valid = true; - m_tokens.clear(); - - // We do not accept \n and \t in the definition. - QRegExp defReg("[\\S ]*"); - if (!defReg.exactMatch(m_definition) && !p_allowAllSpaces) { - m_valid = false; - return; - } - - if (checkType(MetaWordType::FunctionBased) - || checkType(MetaWordType::Dynamic)) { - if (!m_function) { - m_valid = false; - } - } else if (checkType(MetaWordType::Compound)) { - m_tokens = parseToTokens(m_definition); - if (m_tokens.isEmpty()) { - m_valid = false; - return; - } - - for (auto const & to : m_tokens) { - if (to.isMetaWord()) { - if (!m_manager->contains(to.m_value)) { - // Dependency not defined. - m_valid = false; - break; - } - } - } - } -} - -bool VMetaWord::isValid() const -{ - return m_valid; -} - -QString VMetaWord::evaluate() const -{ - Q_ASSERT(m_valid); - - // Check overridden table first. - QString overriddenVal; - if (m_manager->findOverriddenValue(m_word, overriddenVal)) { - return overriddenVal; - } - - switch (m_type) { - case MetaWordType::Simple: - return m_definition; - - case MetaWordType::FunctionBased: - case MetaWordType::Dynamic: - return m_function(this); - - case MetaWordType::Compound: - { - QHash cache; - return evaluateTokens(m_tokens, cache); - } - - default: - return ""; - } -} - -MetaWordType VMetaWord::getType() const -{ - return m_type; -} - -const QString &VMetaWord::getWord() const -{ - return m_word; -} - -const QString &VMetaWord::getDefinition() const -{ - return m_definition; -} - -const VMetaWordManager *VMetaWord::getManager() const -{ - return m_manager; -} - - -QString VMetaWord::toString() const -{ - QChar typeChar('U'); - switch (m_type) { - case MetaWordType::Simple: - typeChar = 'S'; - break; - - case MetaWordType::FunctionBased: - typeChar = 'F'; - break; - - case MetaWordType::Dynamic: - typeChar = 'D'; - break; - - case MetaWordType::Compound: - typeChar = 'C'; - break; - - default: - break; - } - - return QString("%1%2%1[%3]: %4").arg(VMetaWordManager::c_delimiter) - .arg(m_word) - .arg(typeChar) - .arg(m_definition); -} - -QVector VMetaWord::parseToTokens(const QString &p_text) -{ - QVector tokens; - - TokenType type = TokenType::Raw; - QString value; - value.reserve(p_text.size()); - for (int idx = 0; idx < p_text.size(); ++idx) { - const QChar &ch = p_text[idx]; - if (ch == VMetaWordManager::c_delimiter) { - // Check if it is single or double. - int next = idx + 1; - if (next == p_text.size() - || p_text[next] != VMetaWordManager::c_delimiter) { - // Single delimiter. - if (type == TokenType::Raw) { - // End of a raw token, begin of a MetaWord token. - if (!value.isEmpty()) { - tokens.push_back(Token(type, value)); - } - - type = TokenType::MetaWord; - } else { - // End of a MetaWord token, begin of a Raw token. - Q_ASSERT(!value.isEmpty()); - - tokens.push_back(Token(type, value)); - type = TokenType::Raw; - } - - value.clear(); - } else { - // Double delimiter. - // If now is parsing a MetaWord token, treat the first delimiter - // as the end of a token. - // Otherwise, store one single delimiter in value and skip next char. - if (type == TokenType::MetaWord) { - Q_ASSERT(!value.isEmpty()); - tokens.push_back(Token(type, value)); - type = TokenType::Raw; - value.clear(); - } else { - value.push_back(ch); - ++idx; - } - } - } else { - // Push ch in value. - value.push_back(ch); - } - } - - if (!value.isEmpty()) { - if (type == TokenType::Raw) { - tokens.push_back(Token(type, value)); - } else { - // An imcomplete metaword token. - // Treat it as raw. - tokens.push_back(Token(TokenType::Raw, "%" + value)); - } - - value.clear(); - } - - return tokens; -} - -QString VMetaWord::evaluateTokens(const QVector &p_tokens, - QHash &p_cache) const -{ - QString val; - - for (auto const & to : p_tokens) { - switch (to.m_type) { - case TokenType::Raw: - val += to.m_value; - break; - - case TokenType::MetaWord: - { - const VMetaWord *metaWord = m_manager->findMetaWord(to.m_value); - if (!metaWord) { - // Invalid meta word. Treat it as literal value. - val += VMetaWordManager::c_delimiter + to.m_value + VMetaWordManager::c_delimiter; - break; - } - - QString wordVal; - switch (metaWord->getType()) { - case MetaWordType::FunctionBased: - { - auto it = p_cache.find(metaWord->getWord()); - if (it != p_cache.end()) { - // Find it in the cache. - wordVal = it.value(); - } else { - // First evaluate this meta word. - wordVal = metaWord->evaluate(); - p_cache.insert(metaWord->getWord(), wordVal); - } - - break; - } - - case MetaWordType::Compound: - wordVal = evaluateTokens(metaWord->m_tokens, p_cache); - break; - - default: - wordVal = metaWord->evaluate(); - break; - } - - val += wordVal; - break; - } - - default: - Q_ASSERT(false); - break; - } - } - - return val; -} diff --git a/src/utils/vmetawordmanager.h b/src/utils/vmetawordmanager.h deleted file mode 100644 index a7ae8615..00000000 --- a/src/utils/vmetawordmanager.h +++ /dev/null @@ -1,216 +0,0 @@ -#ifndef VMETAWORDMANAGER_H -#define VMETAWORDMANAGER_H - -#include - -#include -#include -#include -#include -#include -#include - - -enum class MetaWordType -{ - // Definition is plain text. - Simple = 0, - - // Definition is a function call to get the value. - FunctionBased, - - // Like FunctionBased, but should re-evaluate the value for each occurence. - Dynamic, - - // Consists of other meta words. - Compound, - - Invalid -}; - -// We call meta word "magic word" in user interaction. -struct VMagicWord -{ - QString m_name; - QString m_definition; -}; - -class VMetaWordManager; -class VMetaWord; - -typedef std::function MetaWordFunc; - -// A Meta Word is surrounded by %. -// - Use %% for an escaped %; -// - Built-in or user-defined; -// - A meta word could contain other meta words as definition. -class VMetaWord -{ -public: - VMetaWord(const VMetaWordManager *p_manager, - MetaWordType p_type, - const QString &p_word, - const QString &p_definition, - MetaWordFunc p_function = nullptr, - bool p_allowAllSpaces = false); - - bool isValid() const; - - QString evaluate() const; - - MetaWordType getType() const; - - const QString &getWord() const; - - const QString &getDefinition() const; - - const VMetaWordManager *getManager() const; - - QString toString() const; - - enum class TokenType - { - Raw = 0, - MetaWord - }; - - struct Token - { - Token() - : m_type(TokenType::Raw) - { - } - - Token(VMetaWord::TokenType p_type, const QString &p_value) - : m_type(p_type), - m_value(p_value) - { - } - - QString toString() const - { - return QString("token %1[%2]").arg(m_type == TokenType::Raw - ? "Raw" : "MetaWord") - .arg(m_value); - } - - bool isRaw() const - { - return m_type == TokenType::Raw; - } - - bool isMetaWord() const - { - return m_type == TokenType::MetaWord; - } - - TokenType m_type; - - // For Raw type, m_value is the raw string of this token; - // For MetaWord type, m_value is the word of the meta word pointed to by - // this token. - QString m_value; - }; - -private: - // Check if m_type is @p_type. - bool checkType(MetaWordType p_type); - - // Parse children word from definition. - // Children word MUST be defined in m_manager already. - // @p_allowAllSpaces: if true then we allow all spaces including \n and \t - // to appear in the definition. - void checkAndParseDefinition(bool p_allowAllSpaces); - - // Parse @p_text to a list of tokens. - static QVector parseToTokens(const QString &p_text); - - // Used for Compound meta word with cache @p_cache. - // @p_cache: value cache for FunctionBased Token. - // For a meta word occuring more than once, we should evaluate it once for - // FunctionBased meta word. - QString evaluateTokens(const QVector &p_tokens, - QHash &p_cache) const; - - const VMetaWordManager *m_manager; - - MetaWordType m_type; - - // Word could contains spaces but no %. - QString m_word; - - // For Simple/Compound meta word, this contains the definition; - // For FunctionBased/Dynamic meta word, this makes no sense and is used - // for description. - QString m_definition; - - // For FunctionBased and Dynamic meta word. - MetaWordFunc m_function; - - bool m_valid; - - // Tokens used for Compound meta word. - QVector m_tokens; -}; - - -// Manager of meta word. -class VMetaWordManager : public QObject -{ - Q_OBJECT -public: - explicit VMetaWordManager(QObject *p_parent = nullptr); - - void init(); - - // Expand meta words in @p_text and return the expanded text. - // @p_overriddenWords: a table containing overridden meta words. - QString evaluate(const QString &p_text, - const QHash &p_overriddenWords = QHash()) const; - - const VMetaWord *findMetaWord(const QString &p_word) const; - - bool contains(const QString &p_word) const; - - const QDateTime &getDateTime() const; - - const QHash &getAllMetaWords() const; - - // Find @p_word in the overridden table. - // Return true if found and set @p_value to the overridden value. - bool findOverriddenValue(const QString &p_word, QString &p_value) const; - - // % by default. - static const QChar c_delimiter; - -private: - void addMetaWord(MetaWordType p_type, - const QString &p_word, - const QString &p_definition, - MetaWordFunc p_function = nullptr); - - void initCustomMetaWords(); - - // Map using word as key. - QHash m_metaWords; - - // Used for data/time related evaluate. - // Will be updated before each evaluation. - QDateTime m_dateTime; - - // Overridden table containing meta words with their designated value. - // Will be updated before each evaluation and clear after the evaluation. - QHash m_overriddenWords; -}; - -inline const QDateTime &VMetaWordManager::getDateTime() const -{ - return m_dateTime; -} - -inline const QHash &VMetaWordManager::getAllMetaWords() const -{ - return m_metaWords; -} - -#endif // VMETAWORDMANAGER_H diff --git a/src/utils/vpreviewutils.cpp b/src/utils/vpreviewutils.cpp deleted file mode 100644 index 94445516..00000000 --- a/src/utils/vpreviewutils.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "vpreviewutils.h" - -#include -#include - -QTextImageFormat VPreviewUtils::fetchFormatFromPosition(QTextDocument *p_doc, - int p_position) -{ - if (p_doc->characterAt(p_position) != QChar::ObjectReplacementCharacter) { - return QTextImageFormat(); - } - - QTextCursor cursor(p_doc); - cursor.setPosition(p_position); - if (cursor.atBlockEnd()) { - return QTextImageFormat(); - } - - cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1); - - return cursor.charFormat().toImageFormat(); -} - -PreviewImageType VPreviewUtils::getPreviewImageType(const QTextImageFormat &p_format) -{ - Q_ASSERT(p_format.isValid()); - bool ok = true; - int type = p_format.property((int)ImageProperty::ImageType).toInt(&ok); - if (ok) { - return (PreviewImageType)type; - } else { - return PreviewImageType::Invalid; - } -} - -PreviewImageSource VPreviewUtils::getPreviewImageSource(const QTextImageFormat &p_format) -{ - Q_ASSERT(p_format.isValid()); - bool ok = true; - int src = p_format.property((int)ImageProperty::ImageSource).toInt(&ok); - if (ok) { - return (PreviewImageSource)src; - } else { - return PreviewImageSource::Invalid; - } -} - -long long VPreviewUtils::getPreviewImageID(const QTextImageFormat &p_format) -{ - if (!p_format.isValid()) { - return -1; - } - - bool ok = true; - long long id = p_format.property((int)ImageProperty::ImageID).toLongLong(&ok); - if (ok) { - return id; - } else { - return -1; - } -} diff --git a/src/utils/vpreviewutils.h b/src/utils/vpreviewutils.h deleted file mode 100644 index 3cb2a0e6..00000000 --- a/src/utils/vpreviewutils.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef VPREVIEWUTILS_H -#define VPREVIEWUTILS_H - -#include -#include "vconstants.h" - -class QTextDocument; - -class VPreviewUtils -{ -public: - // Fetch the text image format from an image preview position. - static QTextImageFormat fetchFormatFromPosition(QTextDocument *p_doc, - int p_position); - - static PreviewImageType getPreviewImageType(const QTextImageFormat &p_format); - - static PreviewImageSource getPreviewImageSource(const QTextImageFormat &p_format); - - // Fetch the ImageID from an image format. - // Returns -1 if not valid. - static long long getPreviewImageID(const QTextImageFormat &p_format); - -private: - VPreviewUtils() {} -}; - -#endif // VPREVIEWUTILS_H diff --git a/src/utils/vutils.cpp b/src/utils/vutils.cpp deleted file mode 100644 index 9c934ba0..00000000 --- a/src/utils/vutils.cpp +++ /dev/null @@ -1,1130 +0,0 @@ -#include "vutils.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vorphanfile.h" -#include "vnote.h" -#include "vnotebook.h" -#include "hgmarkdownhighlighter.h" - -extern VConfigManager *g_config; - -QVector> VUtils::s_availableLanguages; - -const QString VUtils::c_imageLinkRegExp = QString("\\!\\[([^\\]]*)\\]\\(([^\\)\"]+)\\s*(\"(\\\\.|[^\"\\)])*\")?\\s*\\)"); - -const QString VUtils::c_imageTitleRegExp = QString("[\\w\\(\\)@#%\\*\\-\\+=\\?<>\\,\\.\\s]*"); - -const QString VUtils::c_fileNameRegExp = QString("[^\\\\/:\\*\\?\"<>\\|]*"); - -const QString VUtils::c_fencedCodeBlockStartRegExp = QString("^(\\s*)```([^`\\s]*)\\s*[^`]*$"); - -const QString VUtils::c_fencedCodeBlockEndRegExp = QString("^(\\s*)```$"); - -const QString VUtils::c_previewImageBlockRegExp = QString("[\\n|^][ |\\t]*\\xfffc[ |\\t]*(?=\\n)"); - -const QString VUtils::c_headerRegExp = QString("^(#{1,6})\\s+(((\\d+\\.)+(?=\\s))?\\s*(\\S.*)?)$"); - -const QString VUtils::c_headerPrefixRegExp = QString("^(#{1,6}\\s+((\\d+\\.)+(?=\\s))?\\s*)($|(\\S.*)?$)"); - -void VUtils::initAvailableLanguage() -{ - if (!s_availableLanguages.isEmpty()) { - return; - } - - s_availableLanguages.append(QPair("en_US", "English (US)")); - s_availableLanguages.append(QPair("zh_CN", "Chinese")); -} - -QString VUtils::readFileFromDisk(const QString &filePath) -{ - QFile file(filePath); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - qWarning() << "fail to open file" << filePath << "to read"; - return QString(); - } - QString fileText(file.readAll()); - file.close(); - qDebug() << "read file content:" << filePath; - return fileText; -} - -bool VUtils::writeFileToDisk(const QString &filePath, const QString &text) -{ - QFile file(filePath); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - qWarning() << "fail to open file" << filePath << "to write"; - return false; - } - QTextStream stream(&file); - stream << text; - file.close(); - qDebug() << "write file content:" << filePath; - return true; -} - -bool VUtils::writeJsonToDisk(const QString &p_filePath, const QJsonObject &p_json) -{ - QFile file(p_filePath); - // We use Unix LF for config file. - if (!file.open(QIODevice::WriteOnly)) { - qWarning() << "fail to open file" << p_filePath << "to write"; - return false; - } - - QJsonDocument doc(p_json); - if (-1 == file.write(doc.toJson())) { - return false; - } - - return true; -} - -QJsonObject VUtils::readJsonFromDisk(const QString &p_filePath) -{ - QFile file(p_filePath); - if (!file.open(QIODevice::ReadOnly)) { - qWarning() << "fail to open file" << p_filePath << "to read"; - return QJsonObject(); - } - - return QJsonDocument::fromJson(file.readAll()).object(); -} - -QRgb VUtils::QRgbFromString(const QString &str) -{ - Q_ASSERT(str.length() == 6); - QString rStr = str.left(2); - QString gStr = str.mid(2, 2); - QString bStr = str.right(2); - - bool ok, ret = true; - int red = rStr.toInt(&ok, 16); - ret = ret && ok; - int green = gStr.toInt(&ok, 16); - ret = ret && ok; - int blue = bStr.toInt(&ok, 16); - ret = ret && ok; - - if (ret) { - return qRgb(red, green, blue); - } - qWarning() << "fail to construct QRgb from string" << str; - return QRgb(); -} - -QString VUtils::generateImageFileName(const QString &path, - const QString &title, - const QString &format) -{ - QRegExp regExp("\\W"); - QString baseName(title.toLower()); - - // Remove non-character chars. - baseName.remove(regExp); - - // Constrain the length of the name. - baseName.truncate(10); - - if (!baseName.isEmpty()) { - baseName.prepend('_'); - } - - // Add current time and random number to make the name be most likely unique - baseName = baseName + '_' + QString::number(QDateTime::currentDateTime().toTime_t()); - baseName = baseName + '_' + QString::number(qrand()); - - QDir dir(path); - QString imageName = baseName + "." + format.toLower(); - int index = 1; - - while (fileExists(dir, imageName, true)) { - imageName = QString("%1_%2.%3").arg(baseName).arg(index++) - .arg(format.toLower()); - } - - return imageName; -} - -void VUtils::processStyle(QString &style, const QVector > &varMap) -{ - // Process style - for (int i = 0; i < varMap.size(); ++i) { - const QPair &map = varMap[i]; - style.replace("@" + map.first, map.second); - } -} - -QString VUtils::fileNameFromPath(const QString &p_path) -{ - if (p_path.isEmpty()) { - return p_path; - } - - return QFileInfo(QDir::cleanPath(p_path)).fileName(); -} - -QString VUtils::basePathFromPath(const QString &p_path) -{ - if (p_path.isEmpty()) { - return p_path; - } - - return QFileInfo(QDir::cleanPath(p_path)).path(); -} - -QVector VUtils::fetchImagesFromMarkdownFile(VFile *p_file, - ImageLink::ImageLinkType p_type) -{ - Q_ASSERT(p_file->getDocType() == DocType::Markdown); - QVector images; - - bool isOpened = p_file->isOpened(); - if (!isOpened && !p_file->open()) { - return images; - } - - const QString &text = p_file->getContent(); - if (text.isEmpty()) { - if (!isOpened) { - p_file->close(); - } - - return images; - } - - // Used to de-duplicate the links. Url as the key. - QSet fetchedLinks; - - QVector regions = fetchImageRegionsUsingParser(text); - QRegExp regExp(c_imageLinkRegExp); - QString basePath = p_file->fetchBasePath(); - for (int i = 0; i < regions.size(); ++i) { - const VElementRegion ® = regions[i]; - QString linkText = text.mid(reg.m_startPos, reg.m_endPos - reg.m_startPos); - bool matched = regExp.exactMatch(linkText); - if (!matched) { - // Image links with reference format will not match. - continue; - } - - QString imageUrl = regExp.capturedTexts()[2].trimmed(); - - ImageLink link; - link.m_url = imageUrl; - QFileInfo info(basePath, imageUrl); - if (info.exists()) { - if (info.isNativePath()) { - // Local file. - link.m_path = QDir::cleanPath(info.absoluteFilePath()); - - if (QDir::isRelativePath(imageUrl)) { - link.m_type = p_file->isInternalImageFolder(VUtils::basePathFromPath(link.m_path)) ? - ImageLink::LocalRelativeInternal : ImageLink::LocalRelativeExternal; - } else { - link.m_type = ImageLink::LocalAbsolute; - } - } else { - link.m_type = ImageLink::Resource; - link.m_path = imageUrl; - } - } else { - QUrl url(imageUrl); - link.m_path = url.toString(); - link.m_type = ImageLink::Remote; - } - - if (link.m_type & p_type) { - if (!fetchedLinks.contains(link.m_url)) { - fetchedLinks.insert(link.m_url); - images.push_back(link); - qDebug() << "fetch one image:" << link.m_type << link.m_path << link.m_url; - } - } - } - - if (!isOpened) { - p_file->close(); - } - - return images; -} - -QString VUtils::imageLinkUrlToPath(const QString &p_basePath, const QString &p_url) -{ - QString path; - QFileInfo info(p_basePath, p_url); - if (info.exists()) { - if (info.isNativePath()) { - // Local file. - path = QDir::cleanPath(info.absoluteFilePath()); - } else { - path = p_url; - } - } else { - path = QUrl(p_url).toString(); - } - - return path; -} - -bool VUtils::makePath(const QString &p_path) -{ - if (p_path.isEmpty()) { - return true; - } - - bool ret = true; - QDir dir; - if (dir.mkpath(p_path)) { - qDebug() << "make path" << p_path; - } else { - qWarning() << "fail to make path" << p_path; - ret = false; - } - - return ret; -} - -QJsonObject VUtils::clipboardToJson() -{ - QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - - QJsonObject obj; - if (mimeData->hasText()) { - QString text = mimeData->text(); - obj = QJsonDocument::fromJson(text.toUtf8()).object(); - qDebug() << "Json object in clipboard" << obj; - } - - return obj; -} - -ClipboardOpType VUtils::operationInClipboard() -{ - QJsonObject obj = clipboardToJson(); - if (obj.contains(ClipboardConfig::c_type)) { - return (ClipboardOpType)obj[ClipboardConfig::c_type].toInt(); - } - - return ClipboardOpType::Invalid; -} - -bool VUtils::copyFile(const QString &p_srcFilePath, const QString &p_destFilePath, bool p_isCut) -{ - QString srcPath = QDir::cleanPath(p_srcFilePath); - QString destPath = QDir::cleanPath(p_destFilePath); - - if (srcPath == destPath) { - return true; - } - - QDir dir; - if (!dir.mkpath(basePathFromPath(p_destFilePath))) { - qWarning() << "fail to create directory" << basePathFromPath(p_destFilePath); - return false; - } - - if (p_isCut) { - QFile file(srcPath); - if (!file.rename(destPath)) { - qWarning() << "fail to copy file" << srcPath << destPath; - return false; - } - } else { - if (!QFile::copy(srcPath, destPath)) { - qWarning() << "fail to copy file" << srcPath << destPath; - return false; - } - } - - return true; -} - -bool VUtils::copyDirectory(const QString &p_srcDirPath, const QString &p_destDirPath, bool p_isCut) -{ - QString srcPath = QDir::cleanPath(p_srcDirPath); - QString destPath = QDir::cleanPath(p_destDirPath); - if (srcPath == destPath) { - return true; - } - - if (QFileInfo::exists(destPath)) { - qWarning() << QString("target directory %1 already exists").arg(destPath); - return false; - } - - // QDir.rename() could not move directory across drives. - - // Make sure target directory exists. - QDir destDir(destPath); - if (!destDir.exists()) { - if (!destDir.mkpath(destPath)) { - qWarning() << QString("fail to create target directory %1").arg(destPath); - return false; - } - } - - // Handle directory recursively. - QDir srcDir(srcPath); - Q_ASSERT(srcDir.exists() && destDir.exists()); - QFileInfoList nodes = srcDir.entryInfoList(QDir::Dirs | QDir::Files | QDir::Hidden - | QDir::NoSymLinks | QDir::NoDotAndDotDot); - for (int i = 0; i < nodes.size(); ++i) { - const QFileInfo &fileInfo = nodes.at(i); - QString name = fileInfo.fileName(); - if (fileInfo.isDir()) { - if (!copyDirectory(srcDir.filePath(name), destDir.filePath(name), p_isCut)) { - return false; - } - } else { - Q_ASSERT(fileInfo.isFile()); - if (!copyFile(srcDir.filePath(name), destDir.filePath(name), p_isCut)) { - return false; - } - } - } - - if (p_isCut) { - if (!destDir.rmdir(srcPath)) { - qWarning() << QString("fail to delete source directory %1 after cut").arg(srcPath); - return false; - } - } - - return true; -} - -int VUtils::showMessage(QMessageBox::Icon p_icon, - const QString &p_title, - const QString &p_text, - const QString &p_infoText, - QMessageBox::StandardButtons p_buttons, - QMessageBox::StandardButton p_defaultBtn, - QWidget *p_parent, - MessageBoxType p_type) -{ - QMessageBox msgBox(p_icon, p_title, p_text, p_buttons, p_parent); - msgBox.setInformativeText(p_infoText); - msgBox.setDefaultButton(p_defaultBtn); - - if (p_type == MessageBoxType::Danger) { - QPushButton *okBtn = dynamic_cast(msgBox.button(QMessageBox::Ok)); - if (okBtn) { - setDynamicProperty(okBtn, "DangerBtn"); - } - } - - QPushButton *defaultBtn = dynamic_cast(msgBox.button(p_defaultBtn)); - if (defaultBtn) { - setDynamicProperty(defaultBtn, "SpecialBtn"); - } - - return msgBox.exec(); -} - -QString VUtils::generateCopiedFileName(const QString &p_dirPath, - const QString &p_fileName, - bool p_completeBaseName) -{ - QDir dir(p_dirPath); - if (!dir.exists() || !dir.exists(p_fileName)) { - return p_fileName; - } - - QFileInfo fi(p_fileName); - QString baseName = p_completeBaseName ? fi.completeBaseName() : fi.baseName(); - QString suffix = p_completeBaseName ? fi.suffix() : fi.completeSuffix(); - - int index = 0; - QString fileName; - do { - QString seq; - if (index > 0) { - seq = QString("%1").arg(QString::number(index), 3, '0'); - } - - index++; - fileName = QString("%1_copy%2").arg(baseName).arg(seq); - if (!suffix.isEmpty()) { - fileName = fileName + "." + suffix; - } - } while (fileExists(dir, fileName, true)); - - return fileName; -} - -QString VUtils::generateCopiedDirName(const QString &p_parentDirPath, const QString &p_dirName) -{ - QDir dir(p_parentDirPath); - QString name = p_dirName; - QString dirPath = dir.filePath(name); - int index = 0; - while (QDir(dirPath).exists()) { - QString seq; - if (index > 0) { - seq = QString::number(index); - } - index++; - name = QString("%1_copy%2").arg(p_dirName).arg(seq); - dirPath = dir.filePath(name); - } - return name; -} - -const QVector>& VUtils::getAvailableLanguages() -{ - if (s_availableLanguages.isEmpty()) { - initAvailableLanguage(); - } - - return s_availableLanguages; -} - -bool VUtils::isValidLanguage(const QString &p_lang) -{ - for (auto const &lang : getAvailableLanguages()) { - if (lang.first == p_lang) { - return true; - } - } - - return false; -} - -bool VUtils::isImageURL(const QUrl &p_url) -{ - QString urlStr; - if (p_url.isLocalFile()) { - urlStr = p_url.toLocalFile(); - } else { - urlStr = p_url.toString(); - } - return isImageURLText(urlStr); -} - -bool VUtils::isImageURLText(const QString &p_url) -{ - QFileInfo info(p_url); - return QImageReader::supportedImageFormats().contains(info.suffix().toLower().toLatin1()); -} - -qreal VUtils::calculateScaleFactor() -{ - // const qreal refHeight = 1152; - // const qreal refWidth = 2048; - const qreal refDpi = 96; - - qreal dpi = QGuiApplication::primaryScreen()->logicalDotsPerInch(); - qreal factor = dpi / refDpi; - return factor < 1 ? 1 : factor; -} - -bool VUtils::realEqual(qreal p_a, qreal p_b) -{ - return std::abs(p_a - p_b) < 1e-8; -} - -QChar VUtils::keyToChar(int p_key) -{ - if (p_key >= Qt::Key_A && p_key <= Qt::Key_Z) { - return QChar('a' + p_key - Qt::Key_A); - } - - return QChar(); -} - -QString VUtils::getLocale() -{ - QString locale = g_config->getLanguage(); - if (locale == "System" || !isValidLanguage(locale)) { - locale = QLocale::system().name(); - } - return locale; -} - -void VUtils::sleepWait(int p_milliseconds) -{ - if (p_milliseconds <= 0) { - return; - } - - QElapsedTimer t; - t.start(); - while (t.elapsed() < p_milliseconds) { - QCoreApplication::processEvents(); - } -} - -DocType VUtils::docTypeFromName(const QString &p_name) -{ - if (p_name.isEmpty()) { - return DocType::Unknown; - } - - const QHash> &suffixes = g_config->getDocSuffixes(); - - QString suf = QFileInfo(p_name).suffix().toLower(); - for (auto it = suffixes.begin(); it != suffixes.end(); ++it) { - if (it.value().contains(suf)) { - return DocType(it.key()); - } - } - - return DocType::Unknown; -} - -QString VUtils::generateHtmlTemplate(MarkdownConverterType p_conType, bool p_exportPdf) -{ - QString jsFile, extraFile; - switch (p_conType) { - case MarkdownConverterType::Marked: - jsFile = "qrc" + VNote::c_markedJsFile; - extraFile = "\n"; - break; - - case MarkdownConverterType::Hoedown: - jsFile = "qrc" + VNote::c_hoedownJsFile; - // Use Marked to highlight code blocks. - extraFile = "\n"; - break; - - case MarkdownConverterType::MarkdownIt: - { - jsFile = "qrc" + VNote::c_markdownitJsFile; - extraFile = "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n"; - - MarkdownitOption opt = g_config->getMarkdownitOption(); - QString optJs = QString("\n") - .arg(opt.m_html ? "true" : "false") - .arg(opt.m_breaks ? "true" : "false") - .arg(opt.m_linkify ? "true" : "false"); - extraFile += optJs; - break; - } - - case MarkdownConverterType::Showdown: - jsFile = "qrc" + VNote::c_showdownJsFile; - extraFile = "\n" + - "\n"; - - break; - - default: - Q_ASSERT(false); - } - - if (g_config->getEnableMermaid()) { - extraFile += "\n" + - "\n" + - "\n"; - } - - if (g_config->getEnableFlowchart()) { - extraFile += "\n" + - "\n" + - "\n"; - } - - if (g_config->getEnableMathjax()) { - extraFile += "\n" - "\n" + - "\n"; - } - - if (g_config->getEnableImageCaption()) { - extraFile += "\n"; - } - - if (g_config->getEnableCodeBlockLineNumber()) { - extraFile += "\n" + - "\n"; - } - - QString htmlTemplate; - if (p_exportPdf) { - htmlTemplate = VNote::s_markdownTemplatePDF; - } else { - htmlTemplate = VNote::s_markdownTemplate; - } - - htmlTemplate.replace(c_htmlJSHolder, jsFile); - if (!extraFile.isEmpty()) { - htmlTemplate.replace(c_htmlExtraHolder, extraFile); - } - - return htmlTemplate; -} - -QString VUtils::getFileNameWithSequence(const QString &p_directory, - const QString &p_baseFileName, - bool p_completeBaseName) -{ - QDir dir(p_directory); - if (!dir.exists() || !dir.exists(p_baseFileName)) { - return p_baseFileName; - } - - // Append a sequence. - QFileInfo fi(p_baseFileName); - QString baseName = p_completeBaseName ? fi.completeBaseName() : fi.baseName(); - QString suffix = p_completeBaseName ? fi.suffix() : fi.completeSuffix(); - int seq = 1; - QString fileName; - do { - fileName = QString("%1_%2").arg(baseName).arg(QString::number(seq++), 3, '0'); - if (!suffix.isEmpty()) { - fileName = fileName + "." + suffix; - } - } while (fileExists(dir, fileName, true)); - - return fileName; -} - -QString VUtils::getDirNameWithSequence(const QString &p_directory, - const QString &p_baseDirName) -{ - QDir dir(p_directory); - if (!dir.exists() || !dir.exists(p_baseDirName)) { - return p_baseDirName; - } - - // Append a sequence. - int seq = 1; - QString fileName; - do { - fileName = QString("%1_%2").arg(p_baseDirName).arg(QString::number(seq++), 3, '0'); - } while (fileExists(dir, fileName, true)); - - return fileName; -} - -QString VUtils::getRandomFileName(const QString &p_directory) -{ - Q_ASSERT(!p_directory.isEmpty()); - - QString name; - QDir dir(p_directory); - do { - name = QString::number(QDateTime::currentDateTimeUtc().toTime_t()); - name = name + '_' + QString::number(qrand()); - } while (fileExists(dir, name, true)); - - return name; -} - -bool VUtils::checkPathLegal(const QString &p_path) -{ - // Ensure every part of the p_path is a valid file name until we come to - // an existing parent directory. - if (p_path.isEmpty()) { - return false; - } - - if (QFileInfo::exists(p_path)) { -#if defined(Q_OS_WIN) - // On Windows, "/" and ":" will also make exists() return true. - if (p_path.startsWith('/') || p_path == ":") { - return false; - } -#endif - - return true; - } - - bool ret = false; - int pos; - QString basePath = basePathFromPath(p_path); - QString fileName = fileNameFromPath(p_path); - QValidator *validator = new QRegExpValidator(QRegExp(c_fileNameRegExp)); - while (!fileName.isEmpty()) { - QValidator::State validFile = validator->validate(fileName, pos); - if (validFile != QValidator::Acceptable) { - break; - } - - if (QFileInfo::exists(basePath)) { - ret = true; - -#if defined(Q_OS_WIN) - // On Windows, "/" and ":" will also make exists() return true. - if (basePath.startsWith('/') || basePath == ":") { - ret = false; - } -#endif - - break; - } - - fileName = fileNameFromPath(basePath); - basePath = basePathFromPath(basePath); - } - - delete validator; - return ret; -} - -bool VUtils::checkFileNameLegal(const QString &p_name) -{ - if (p_name.isEmpty()) { - return false; - } - - QRegExp exp(c_fileNameRegExp); - return exp.exactMatch(p_name); -} - -bool VUtils::equalPath(const QString &p_patha, const QString &p_pathb) -{ - QString a = QDir::cleanPath(p_patha); - QString b = QDir::cleanPath(p_pathb); - -#if defined(Q_OS_WIN) - a = a.toLower(); - b = b.toLower(); -#endif - - return a == b; -} - -bool VUtils::splitPathInBasePath(const QString &p_base, - const QString &p_path, - QStringList &p_parts) -{ - p_parts.clear(); - QString a = QDir::cleanPath(p_base); - QString b = QDir::cleanPath(p_path); - -#if defined(Q_OS_WIN) - if (!b.toLower().startsWith(a.toLower())) { - return false; - } -#else - if (!b.startsWith(a)) { - return false; - } -#endif - - if (a.size() == b.size()) { - return true; - } - - Q_ASSERT(a.size() < b.size()); - - if (b.at(a.size()) != '/') { - return false; - } - - p_parts = b.right(b.size() - a.size() - 1).split("/", QString::SkipEmptyParts); - - qDebug() << QString("split path %1 based on %2 to %3 parts").arg(p_path).arg(p_base).arg(p_parts.size()); - return true; -} - -void VUtils::decodeUrl(QString &p_url) -{ - QHash maps; - maps.insert("%20", " "); - - for (auto it = maps.begin(); it != maps.end(); ++it) { - p_url.replace(it.key(), it.value()); - } -} - -QString VUtils::getShortcutText(const QString &p_keySeq) -{ - return QKeySequence(p_keySeq).toString(QKeySequence::NativeText); -} - -bool VUtils::deleteDirectory(const VNotebook *p_notebook, - const QString &p_path, - bool p_skipRecycleBin) -{ - if (p_skipRecycleBin) { - QDir dir(p_path); - return dir.removeRecursively(); - } else { - // Move it to the recycle bin folder. - return deleteFile(p_notebook->getRecycleBinFolderPath(), p_path); - } -} - -bool VUtils::emptyDirectory(const VNotebook *p_notebook, - const QString &p_path, - bool p_skipRecycleBin) -{ - QDir dir(p_path); - if (!dir.exists()) { - return true; - } - - QFileInfoList nodes = dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::Hidden - | QDir::NoSymLinks | QDir::NoDotAndDotDot); - for (int i = 0; i < nodes.size(); ++i) { - const QFileInfo &fileInfo = nodes.at(i); - if (fileInfo.isDir()) { - if (!deleteDirectory(p_notebook, fileInfo.absoluteFilePath(), p_skipRecycleBin)) { - return false; - } - } else { - Q_ASSERT(fileInfo.isFile()); - if (!deleteFile(p_notebook, fileInfo.absoluteFilePath(), p_skipRecycleBin)) { - return false; - } - } - } - - return true; -} - -bool VUtils::deleteFile(const VNotebook *p_notebook, - const QString &p_path, - bool p_skipRecycleBin) -{ - if (p_skipRecycleBin) { - QFile file(p_path); - return file.remove(); - } else { - // Move it to the recycle bin folder. - return deleteFile(p_notebook->getRecycleBinFolderPath(), p_path); - } -} - -bool VUtils::deleteFile(const QString &p_path) -{ - QFile file(p_path); - bool ret = file.remove(); - if (ret) { - qDebug() << "deleted file" << p_path; - } else { - qWarning() << "fail to delete file" << p_path; - } - - return ret; -} - -bool VUtils::deleteFile(const VOrphanFile *p_file, - const QString &p_path, - bool p_skipRecycleBin) -{ - if (p_skipRecycleBin) { - QFile file(p_path); - return file.remove(); - } else { - // Move it to the recycle bin folder. - return deleteFile(p_file->fetchRecycleBinFolderPath(), p_path); - } -} - -static QString getRecycleBinSubFolderToUse(const QString &p_folderPath) -{ - QDir dir(p_folderPath); - return QDir::cleanPath(dir.absoluteFilePath(QDateTime::currentDateTime().toString("yyyyMMdd"))); -} - -bool VUtils::deleteFile(const QString &p_recycleBinFolderPath, - const QString &p_path) -{ - QString binPath = getRecycleBinSubFolderToUse(p_recycleBinFolderPath); - QDir binDir(binPath); - if (!binDir.exists()) { - binDir.mkpath(binPath); - if (!binDir.exists()) { - return false; - } - } - - QString destName = getFileNameWithSequence(binPath, - fileNameFromPath(p_path), - true); - - qDebug() << "try to move" << p_path << "to" << binPath << "as" << destName; - if (!binDir.rename(p_path, binDir.filePath(destName))) { - qWarning() << "fail to move" << p_path << "to" << binDir.filePath(destName); - return false; - } - - return true; -} - -QVector VUtils::fetchImageRegionsUsingParser(const QString &p_content) -{ - Q_ASSERT(!p_content.isEmpty()); - QVector regs; - - QByteArray ba = p_content.toUtf8(); - const char *data = (const char *)ba.data(); - int len = ba.size(); - - pmh_element **result = NULL; - char *content = new char[len + 1]; - memcpy(content, data, len); - content[len] = '\0'; - - pmh_markdown_to_elements(content, pmh_EXT_NONE, &result); - - if (!result) { - return regs; - } - - pmh_element *elem = result[pmh_IMAGE]; - while (elem != NULL) { - if (elem->end <= elem->pos) { - elem = elem->next; - continue; - } - - regs.push_back(VElementRegion(elem->pos, elem->end)); - - elem = elem->next; - } - - pmh_free_elements(result); - - return regs; -} - -QString VUtils::displayDateTime(const QDateTime &p_dateTime) -{ - QString res = p_dateTime.date().toString(Qt::DefaultLocaleLongDate); - res += " " + p_dateTime.time().toString(); - return res; -} - -bool VUtils::fileExists(const QDir &p_dir, const QString &p_name, bool p_forceCaseInsensitive) -{ - if (!p_forceCaseInsensitive) { - return p_dir.exists(p_name); - } - - QString name = p_name.toLower(); - QStringList names = p_dir.entryList(QDir::Dirs | QDir::Files | QDir::Hidden - | QDir::NoSymLinks | QDir::NoDotAndDotDot); - foreach (const QString &str, names) { - if (str.toLower() == name) { - return true; - } - } - - return false; -} - -void VUtils::addErrMsg(QString *p_msg, const QString &p_str) -{ - if (!p_msg) { - return; - } - - if (p_msg->isEmpty()) { - *p_msg = p_str; - } else { - *p_msg = *p_msg + '\n' + p_str; - } -} - -QStringList VUtils::filterFilePathsToOpen(const QStringList &p_files) -{ - QStringList paths; - for (int i = 0; i < p_files.size(); ++i) { - QString path = validFilePathToOpen(p_files[i]); - if (!path.isEmpty()) { - paths.append(path); - } - } - - return paths; -} - -QString VUtils::validFilePathToOpen(const QString &p_file) -{ - if (QFileInfo::exists(p_file)) { - QFileInfo fi(p_file); - if (fi.isFile()) { - // Need to use absolute path here since VNote may be launched - // in different working directory. - return QDir::cleanPath(fi.absoluteFilePath()); - } - } - - return QString(); -} - -bool VUtils::isControlModifierForVim(int p_modifiers) -{ -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - return p_modifiers == Qt::MetaModifier; -#else - return p_modifiers == Qt::ControlModifier; -#endif -} - -void VUtils::touchFile(const QString &p_file) -{ - QFile file(p_file); - if (!file.open(QIODevice::WriteOnly)) { - qWarning() << "fail to touch file" << p_file; - return; - } - - file.close(); -} - -bool VUtils::isMetaKey(int p_key) -{ - return p_key == Qt::Key_Control - || p_key == Qt::Key_Shift - || p_key == Qt::Key_Meta - || p_key == Qt::Key_Alt; -} - -QComboBox *VUtils::getComboBox(QWidget *p_parent) -{ - QComboBox *box = new QComboBox(p_parent); - QStyledItemDelegate *itemDelegate = new QStyledItemDelegate(box); - box->setItemDelegate(itemDelegate); - - return box; -} - -void VUtils::setDynamicProperty(QWidget *p_widget, const char *p_prop, bool p_val) -{ - p_widget->setProperty(p_prop, p_val); - p_widget->style()->unpolish(p_widget); - p_widget->style()->polish(p_widget); -} diff --git a/src/utils/vutils.h b/src/utils/vutils.h deleted file mode 100644 index bf998d94..00000000 --- a/src/utils/vutils.h +++ /dev/null @@ -1,336 +0,0 @@ -#ifndef VUTILS_H -#define VUTILS_H - -#include -#include -#include -#include -#include -#include -#include -#include "vconfigmanager.h" -#include "vconstants.h" - -class QKeyEvent; -class VFile; -class VOrphanFile; -class VNotebook; -class QWidget; -class QComboBox; - -#if !defined(V_ASSERT) - #define V_ASSERT(cond) ((!(cond)) ? qt_assert(#cond, __FILE__, __LINE__) : qt_noop()) -#endif - -// Thanks to CGAL/cgal. -#ifndef __has_attribute - #define __has_attribute(x) 0 // Compatibility with non-clang compilers. -#endif - -#ifndef __has_cpp_attribute - #define __has_cpp_attribute(x) 0 // Compatibility with non-supporting compilers. -#endif - -// The fallthrough attribute. -// See for clang: -// http://clang.llvm.org/docs/AttributeReference.html#statement-attributes -// See for gcc: -// https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html -#if __has_cpp_attribute(fallthrough) -# define V_FALLTHROUGH [[fallthrough]] -#elif __has_cpp_attribute(gnu::fallthrough) -# define V_FALLTHROUGH [[gnu::fallthrough]] -#elif __has_cpp_attribute(clang::fallthrough) -# define V_FALLTHROUGH [[clang::fallthrough]] -#elif __has_attribute(fallthrough) && ! __clang__ -# define V_FALLTHROUGH __attribute__ ((fallthrough)) -#else -# define V_FALLTHROUGH while(false){} -#endif - -enum class MessageBoxType -{ - Normal = 0, - Danger = 1 -}; - -struct ImageLink -{ - enum ImageLinkType - { - LocalRelativeInternal = 0x1, - LocalRelativeExternal = 0x2, - LocalAbsolute = 0x4, - Resource = 0x8, - Remote = 0x10, - All = 0xffff - }; - - QString m_path; - - // The url text in the link. - QString m_url; - - ImageLinkType m_type; -}; - -class VUtils -{ -public: - static QString readFileFromDisk(const QString &filePath); - - static bool writeFileToDisk(const QString &filePath, const QString &text); - - static bool writeJsonToDisk(const QString &p_filePath, const QJsonObject &p_json); - - static QJsonObject readJsonFromDisk(const QString &p_filePath); - - // Transform FFFFFF string to QRgb - static QRgb QRgbFromString(const QString &str); - - static QString generateImageFileName(const QString &path, const QString &title, - const QString &format = "png"); - - // Given the file name @p_fileName and directory path @p_dirPath, generate - // a file name based on @p_fileName which does not exist in @p_dirPath. - // @p_completeBaseName: use complete base name or complete suffix. For example, - // "abc.tar.gz", if @p_completeBaseName is true, the base name is "abc.tar", - // otherwise, it is "abc". - static QString generateCopiedFileName(const QString &p_dirPath, - const QString &p_fileName, - bool p_completeBaseName = true); - - // Given the directory name @p_dirName and directory path @p_parentDirPath, - // generate a directory name based on @p_dirName which does not exist in - // @p_parentDirPath. - static QString generateCopiedDirName(const QString &p_parentDirPath, - const QString &p_dirName); - - static void processStyle(QString &style, const QVector > &varMap); - - // Return the last directory name of @p_path. - static QString directoryNameFromPath(const QString& p_path); - - // Return the file name of @p_path. - // /home/tamlok/abc, /home/tamlok/abc/ will both return abc. - static QString fileNameFromPath(const QString &p_path); - - // Return the base path of @p_path. - // /home/tamlok/abc, /home/tamlok/abc/ will both return /home/tamlok. - static QString basePathFromPath(const QString &p_path); - - // Fetch all the image links in markdown file p_file. - // @p_type to filter the links returned. - // Need to open p_file and will close it if it is originally closed. - static QVector fetchImagesFromMarkdownFile(VFile *p_file, - ImageLink::ImageLinkType p_type = ImageLink::All); - - // Return the absolute path of @p_url according to @p_basePath. - static QString imageLinkUrlToPath(const QString &p_basePath, const QString &p_url); - - // Create directories along the @p_path. - // @p_path could be /home/tamlok/abc, /home/tamlok/abc/. - static bool makePath(const QString &p_path); - - // Return QJsonObject if there is valid Json string in clipboard. - // Return empty object if there is no valid Json string. - static QJsonObject clipboardToJson(); - - // Get the operation type in system's clipboard. - static ClipboardOpType operationInClipboard(); - - static ClipboardOpType opTypeInClipboard() { return ClipboardOpType::Invalid; } - - // Copy file @p_srcFilePath to @p_destFilePath. - // Will make necessary parent directory along the destination path. - static bool copyFile(const QString &p_srcFilePath, const QString &p_destFilePath, bool p_isCut); - - // Copy @p_srcDirPath to be @p_destDirPath. - // @p_destDirPath should not exist. - // Will make necessary parent directory along the destination path. - static bool copyDirectory(const QString &p_srcDirPath, const QString &p_destDirPath, bool p_isCut); - - static int showMessage(QMessageBox::Icon p_icon, const QString &p_title, const QString &p_text, - const QString &p_infoText, QMessageBox::StandardButtons p_buttons, - QMessageBox::StandardButton p_defaultBtn, QWidget *p_parent, - MessageBoxType p_type = MessageBoxType::Normal); - static const QVector > &getAvailableLanguages(); - static bool isValidLanguage(const QString &p_lang); - static bool isImageURL(const QUrl &p_url); - static bool isImageURLText(const QString &p_url); - static qreal calculateScaleFactor(); - static bool realEqual(qreal p_a, qreal p_b); - static QChar keyToChar(int p_key); - static QString getLocale(); - - static void sleepWait(int p_milliseconds); - - // Return the DocType according to suffix. - static DocType docTypeFromName(const QString &p_name); - - // Generate HTML template. - static QString generateHtmlTemplate(MarkdownConverterType p_conType, bool p_exportPdf); - - // Get an available file name in @p_directory with base @p_baseFileName. - // If there already exists a file named @p_baseFileName, try to add sequence - // suffix to the name, such as _001. - // @p_completeBaseName: use complete base name or complete suffix. For example, - // "abc.tar.gz", if @p_completeBaseName is true, the base name is "abc.tar", - // otherwise, it is "abc". - static QString getFileNameWithSequence(const QString &p_directory, - const QString &p_baseFileName, - bool p_completeBaseName = true); - - // Get an available directory name in @p_directory with base @p_baseDirName. - // If there already exists a file named @p_baseFileName, try to add sequence - // suffix to the name, such as _001. - static QString getDirNameWithSequence(const QString &p_directory, - const QString &p_baseDirName); - - // Get an available random file name in @p_directory. - static QString getRandomFileName(const QString &p_directory); - - // Try to check if @p_path is legal. - static bool checkPathLegal(const QString &p_path); - - // Check if file/folder name is legal. - static bool checkFileNameLegal(const QString &p_name); - - // Returns true if @p_patha and @p_pathb points to the same file/directory. - static bool equalPath(const QString &p_patha, const QString &p_pathb); - - // Try to split @p_path into multiple parts based on @p_base. - // Returns false if @p_path is not under @p_base directory. - // @p_parts will be empty if @p_path is right @p_base. - // Example: "/home/tamlok/study", "/home/tamlok/study/a/b/c/vnote.md" - // returns true and @p_parts is {a, b, c, vnote.md}. - static bool splitPathInBasePath(const QString &p_base, - const QString &p_path, - QStringList &p_parts); - - // Decode URL by simply replacing meta-characters. - static void decodeUrl(QString &p_url); - - // Returns the shortcut text. - static QString getShortcutText(const QString &p_keySeq); - - // Delete directory recursively specified by @p_path. - // Will just move the directory to the recycle bin of @p_notebook if - // @p_skipRecycleBin is false. - static bool deleteDirectory(const VNotebook *p_notebook, - const QString &p_path, - bool p_skipRecycleBin = false); - - // Empty all files in directory recursively specified by @p_path. - // Will just move files to the recycle bin of @p_notebook if - // @p_skipRecycleBin is false. - static bool emptyDirectory(const VNotebook *p_notebook, - const QString &p_path, - bool p_skipRecycleBin = false); - - // Delete file specified by @p_path. - // Will just move the file to the recycle bin of @p_notebook if - // @p_skipRecycleBin is false. - static bool deleteFile(const VNotebook *p_notebook, - const QString &p_path, - bool p_skipRecycleBin = false); - - // Delete file specified by @p_path. - // Will just move the file to the recycle bin of VOrphanFile if - // @p_skipRecycleBin is false. - static bool deleteFile(const VOrphanFile *p_file, - const QString &p_path, - bool p_skipRecycleBin = false); - - // Delete file specified by @p_path. - static bool deleteFile(const QString &p_path); - - static QString displayDateTime(const QDateTime &p_dateTime); - - // Check if file @p_name exists in @p_dir. - // @p_forceCaseInsensitive: if true, will check the name ignoring the case. - static bool fileExists(const QDir &p_dir, const QString &p_name, bool p_forceCaseInsensitive = false); - - // Assign @p_str to @p_msg if it is not NULL. - static void addErrMsg(QString *p_msg, const QString &p_str); - - // Check each file of @p_files and return valid ones for VNote to open. - static QStringList filterFilePathsToOpen(const QStringList &p_files); - - // Return the normalized file path of @p_file if it is valid to open. - // Return empty if it is not valid. - static QString validFilePathToOpen(const QString &p_file); - - // See if @p_modifiers is Control which is different on macOs and Windows. - static bool isControlModifierForVim(int p_modifiers); - - // If @p_file does not exists, create an empty file. - static void touchFile(const QString &p_file); - - // Ctrl, Meta, Shift, Alt. - static bool isMetaKey(int p_key); - - // Create and return a QComboBox. - static QComboBox *getComboBox(QWidget *p_parent = nullptr); - - static void setDynamicProperty(QWidget *p_widget, const char *p_prop, bool p_val = true); - - // Regular expression for image link. - // ![image title]( http://github.com/tamlok/vnote.jpg "alt \" text" ) - // Captured texts (need to be trimmed): - // 1. Image Alt Text (Title); - // 2. Image URL; - // 3. Image Optional Title with double quotes; - // 4. Unused; - static const QString c_imageLinkRegExp; - - // Regular expression for image title. - static const QString c_imageTitleRegExp; - - // Regular expression for file/directory name. - // Forbidden char: \/:*?"<>| - static const QString c_fileNameRegExp; - - // Regular expression for fenced code block. - static const QString c_fencedCodeBlockStartRegExp; - static const QString c_fencedCodeBlockEndRegExp; - - // Regular expression for preview image block. - static const QString c_previewImageBlockRegExp; - - // Regular expression for header block. - // Captured texts: - // 1. Header marker (##); - // 2. Header Title (need to be trimmed); - // 3. Header Sequence (1.1., 1.2., optional); - // 4. Unused; - static const QString c_headerRegExp; - - // Regular expression for header block. - // Captured texts: - // 1. prefix till the real header title content; - static const QString c_headerPrefixRegExp; - -private: - VUtils() {} - - static void initAvailableLanguage(); - - // Use HGMarkdownParser to parse @p_content to get all image link regions. - static QVector fetchImageRegionsUsingParser(const QString &p_content); - - // Delete file/directory specified by @p_path by moving it to the recycle bin - // folder @p_recycleBinFolderPath. - static bool deleteFile(const QString &p_recycleBinFolderPath, - const QString &p_path); - - // - static QVector> s_availableLanguages; -}; - -inline QString VUtils::directoryNameFromPath(const QString &p_path) -{ - return fileNameFromPath(p_path); -} - -#endif // VUTILS_H diff --git a/src/utils/vvim.cpp b/src/utils/vvim.cpp deleted file mode 100644 index 53c11188..00000000 --- a/src/utils/vvim.cpp +++ /dev/null @@ -1,6349 +0,0 @@ -#include "vvim.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "vconfigmanager.h" -#include "veditor.h" -#include "utils/veditutils.h" -#include "vconstants.h" -#include "vmdeditor.h" - -extern VConfigManager *g_config; - -const QChar VVim::c_unnamedRegister = QChar('"'); -const QChar VVim::c_blackHoleRegister = QChar('_'); -const QChar VVim::c_selectionRegister = QChar('+'); -QMap VVim::s_registers; - -const int VVim::SearchHistory::c_capacity = 50; - -#define ADDKEY(x, y) case (x): {ch = (y); break;} - -// Returns NULL QChar if invalid. -static QChar keyToChar(int p_key, int p_modifiers) -{ - if (p_key >= Qt::Key_0 && p_key <= Qt::Key_9) { - return QChar('0' + (p_key - Qt::Key_0)); - } else if (p_key >= Qt::Key_A && p_key <= Qt::Key_Z) { - if (p_modifiers == Qt::ShiftModifier - || VUtils::isControlModifierForVim(p_modifiers)) { - return QChar('A' + (p_key - Qt::Key_A)); - } else { - return QChar('a' + (p_key - Qt::Key_A)); - } - } - - QChar ch; - switch (p_key) { - ADDKEY(Qt::Key_Tab, '\t'); - ADDKEY(Qt::Key_Space, ' '); - ADDKEY(Qt::Key_Exclam, '!'); - ADDKEY(Qt::Key_QuoteDbl, '"'); - ADDKEY(Qt::Key_NumberSign, '#'); - ADDKEY(Qt::Key_Dollar, '$'); - ADDKEY(Qt::Key_Percent, '%'); - ADDKEY(Qt::Key_Ampersand, '&'); - ADDKEY(Qt::Key_Apostrophe, '\''); - ADDKEY(Qt::Key_ParenLeft, '('); - ADDKEY(Qt::Key_ParenRight, ')'); - ADDKEY(Qt::Key_Asterisk, '*'); - ADDKEY(Qt::Key_Plus, '+'); - ADDKEY(Qt::Key_Comma, ','); - ADDKEY(Qt::Key_Minus, '-'); - ADDKEY(Qt::Key_Period, '.'); - ADDKEY(Qt::Key_Slash, '/'); - ADDKEY(Qt::Key_Colon, ':'); - ADDKEY(Qt::Key_Semicolon, ';'); - ADDKEY(Qt::Key_Less, '<'); - ADDKEY(Qt::Key_Equal, '='); - ADDKEY(Qt::Key_Greater, '>'); - ADDKEY(Qt::Key_Question, '?'); - ADDKEY(Qt::Key_At, '@'); - ADDKEY(Qt::Key_BracketLeft, '['); - ADDKEY(Qt::Key_Backslash, '\\'); - ADDKEY(Qt::Key_BracketRight, ']'); - ADDKEY(Qt::Key_AsciiCircum, '^'); - ADDKEY(Qt::Key_Underscore, '_'); - ADDKEY(Qt::Key_QuoteLeft, '`'); - ADDKEY(Qt::Key_BraceLeft, '{'); - ADDKEY(Qt::Key_Bar, '|'); - ADDKEY(Qt::Key_BraceRight, '}'); - ADDKEY(Qt::Key_AsciiTilde, '~'); - - default: - break; - } - - return ch; -} - -static QString keyToString(int p_key, int p_modifiers) -{ - QChar ch = keyToChar(p_key, p_modifiers); - if (ch.isNull()) { - return QString(); - } - - if (VUtils::isControlModifierForVim(p_modifiers)) { - return QString("^") + ch; - } else { - return ch; - } -} - -VVim::VVim(VEditor *p_editor) - : QObject(p_editor->getEditor()), - m_editor(p_editor), - m_editConfig(&p_editor->getConfig()), - m_mode(VimMode::Invalid), - m_resetPositionInBlock(true), - m_regName(c_unnamedRegister), - m_leaderKey(Key(Qt::Key_Space)), - m_replayLeaderSequence(false), - m_registerPending(false), - m_insertModeAfterCommand(false), - m_positionBeforeVisualMode(0) -{ - Q_ASSERT(m_editConfig->m_enableVimMode); - - setMode(VimMode::Normal); - - initRegisters(); - - connect(m_editor->object(), &VEditorObject::mousePressed, - this, &VVim::handleMousePressed); - connect(m_editor->object(), &VEditorObject::mouseMoved, - this, &VVim::handleMouseMoved); - connect(m_editor->object(), &VEditorObject::mouseReleased, - this, &VVim::handleMouseReleased); -} - -// Set @p_cursor's position specified by @p_positionInBlock. -// If @p_positionInBlock is bigger than the block's length, move to the end of block. -// Need to setTextCursor() after calling this. -static void setCursorPositionInBlock(QTextCursor &p_cursor, int p_positionInBlock, - QTextCursor::MoveMode p_mode) -{ - QTextBlock block = p_cursor.block(); - if (block.length() > p_positionInBlock) { - p_cursor.setPosition(block.position() + p_positionInBlock, p_mode); - } else { - p_cursor.movePosition(QTextCursor::EndOfBlock, p_mode, 1); - } -} - -// Find the start and end of the spaces @p_cursor locates in (within a single block). -// @p_start and @p_end will be the global position of the start and end of the spaces. -// @p_start will equals to @p_end if @p_cursor is not a space. -static void findCurrentSpace(const QTextCursor &p_cursor, int &p_start, int &p_end) -{ - QTextBlock block = p_cursor.block(); - QString text = block.text(); - int pib = p_cursor.positionInBlock(); - - if (pib < text.size() && !text[pib].isSpace()) { - p_start = p_end = p_cursor.position(); - return; - } - - p_start = 0; - for (int i = pib - 1; i >= 0; --i) { - if (!text[i].isSpace()) { - p_start = i + 1; - break; - } - } - - p_end = block.length() - 1; - for (int i = pib; i < text.size(); ++i) { - if (!text[i].isSpace()) { - p_end = i; - break; - } - } - - p_start += block.position(); - p_end += block.position(); -} - -// Move @p_cursor to skip spaces if current cursor is placed at a space -// (may move across blocks). It will stop by the empty block on the way. -// Forward: wwwwsssss|wwww -// Backward: wwww|ssssswwww -static void moveCursorAcrossSpaces(QTextCursor &p_cursor, - QTextCursor::MoveMode p_mode, - bool p_forward, - bool p_stopAtBoundary = false) -{ - while (true) { - QTextBlock block = p_cursor.block(); - QString text = block.text(); - int pib = p_cursor.positionInBlock(); - - if (p_forward) { - for (; pib < text.size(); ++pib) { - if (!text[pib].isSpace()) { - break; - } - } - - if (pib == text.size() && !p_stopAtBoundary) { - // Move to next block. - p_cursor.movePosition(QTextCursor::Down, p_mode, 1); - if (block.blockNumber() == p_cursor.block().blockNumber()) { - // Already at the last block. - p_cursor.movePosition(QTextCursor::EndOfBlock, p_mode, 1); - break; - } else { - p_cursor.movePosition(QTextCursor::StartOfBlock, p_mode, 1); - if (p_cursor.block().length() <= 1) { - break; - } - } - } else { - // Found non-space character. - p_cursor.setPosition(block.position() + pib, p_mode); - break; - } - } else { - int idx = pib - 1; - for (; idx >= 0; --idx) { - if (!text[idx].isSpace()) { - break; - } - } - - if (idx == -1 && !p_stopAtBoundary) { - // Move to previous block. - p_cursor.movePosition(QTextCursor::Up, p_mode, 1); - if (block.blockNumber() == p_cursor.block().blockNumber()) { - // Already at the first block. - p_cursor.movePosition(QTextCursor::StartOfBlock, p_mode, 1); - break; - } else { - p_cursor.movePosition(QTextCursor::EndOfBlock, p_mode, 1); - if (p_cursor.block().length() <= 1) { - break; - } - } - } else { - // Found non-space character. - p_cursor.setPosition(block.position() + idx + 1, p_mode); - break; - } - } - } -} - -// Expand the selection of @p_cursor to contain additional spaces at the two ends -// within a block. -static void expandSelectionAcrossSpacesWithinBlock(QTextCursor &p_cursor) -{ - QTextBlock block = p_cursor.block(); - QString text = block.text(); - int start = p_cursor.selectionStart() - block.position(); - int end = p_cursor.selectionEnd() - block.position(); - - for (int i = start - 1; i >= 0; --i) { - if (!text[i].isSpace()) { - start = i + 1; - break; - } - } - - for (int i = end; i < text.size(); ++i) { - if (!text[i].isSpace()) { - end = i; - break; - } - } - - start += block.position(); - end += block.position(); - - if (start == p_cursor.selectionStart() && end == p_cursor.selectionEnd()) { - return; - } - - if (p_cursor.anchor() <= p_cursor.position()) { - p_cursor.setPosition(start, QTextCursor::MoveAnchor); - p_cursor.setPosition(end, QTextCursor::KeepAnchor); - } else { - p_cursor.setPosition(end, QTextCursor::MoveAnchor); - p_cursor.setPosition(start, QTextCursor::KeepAnchor); - } -} - -// In Change action, after deleting selected block text, we need to insert a new -// block for user input. -// @p_deletionStart is the global position of the start of the deletion. -// Should be called immediately after the deletion. -static void insertChangeBlockAfterDeletion(QTextCursor &p_cursor, int p_deletionStart) -{ - if (p_cursor.position() < p_deletionStart) { - // Insert a new block below. - p_cursor.movePosition(QTextCursor::EndOfBlock); - p_cursor.insertBlock(); - } else { - // Insert a new block above. - p_cursor.movePosition(QTextCursor::StartOfBlock); - p_cursor.insertBlock(); - p_cursor.movePosition(QTextCursor::PreviousBlock); - } - - if (g_config->getAutoIndent()) { - VEditUtils::indentBlockAsBlock(p_cursor, false); - } -} - -// Given the percentage of the text, return the corresponding block number. -// Notice that the block number is based on 0. -// Returns -1 if it is not valid. -static int percentageToBlockNumber(const QTextDocument *p_doc, int p_percent) -{ - if (p_percent > 100 || p_percent <= 0) { - return -1; - } - - int nrBlock = p_doc->blockCount(); - int num = nrBlock * (p_percent * 1.0 / 100) - 1; - - return num >= 0 ? num : 0; -} - -// Replace each of the character of selected text with @p_char. -// Returns true if replacement has taken place. -// Need to setTextCursor() after calling this. -static bool replaceSelectedTextWithCharacter(QTextCursor &p_cursor, QChar p_char) -{ - if (!p_cursor.hasSelection()) { - return false; - } - - int start = p_cursor.selectionStart(); - int end = p_cursor.selectionEnd(); - p_cursor.setPosition(start, QTextCursor::MoveAnchor); - while (p_cursor.position() < end) { - if (p_cursor.atBlockEnd()) { - p_cursor.movePosition(QTextCursor::NextCharacter); - } else { - p_cursor.deleteChar(); - // insertText() will move the cursor right after the inserted text. - p_cursor.insertText(p_char); - } - } - - return true; -} - -// Reverse the case of selected text. -// Returns true if the reverse has taken place. -// Need to setTextCursor() after calling this. -static bool reverseSelectedTextCase(QTextCursor &p_cursor) -{ - if (!p_cursor.hasSelection()) { - return false; - } - - QTextDocument *doc = p_cursor.document(); - int start = p_cursor.selectionStart(); - int end = p_cursor.selectionEnd(); - p_cursor.setPosition(start, QTextCursor::MoveAnchor); - while (p_cursor.position() < end) { - if (p_cursor.atBlockEnd()) { - p_cursor.movePosition(QTextCursor::NextCharacter); - } else { - QChar ch = doc->characterAt(p_cursor.position()); - bool changed = false; - if (ch.isLower()) { - ch = ch.toUpper(); - changed = true; - } else if (ch.isUpper()) { - ch = ch.toLower(); - changed = true; - } - - if (changed) { - p_cursor.deleteChar(); - // insertText() will move the cursor right after the inserted text. - p_cursor.insertText(ch); - } else { - p_cursor.movePosition(QTextCursor::NextCharacter); - } - } - } - - return true; -} - -// Join current cursor line and the next line. -static void joinTwoLines(QTextCursor &p_cursor, bool p_modifySpaces) -{ - QTextDocument *doc = p_cursor.document(); - QTextBlock firstBlock = p_cursor.block(); - QString textToAppend = firstBlock.next().text(); - p_cursor.movePosition(QTextCursor::EndOfBlock); - - if (p_modifySpaces) { - bool insertSpaces = false; - if (firstBlock.length() > 1) { - QChar lastChar = doc->characterAt(p_cursor.position() - 1); - if (!lastChar.isSpace()) { - insertSpaces = true; - } - } - - if (insertSpaces) { - p_cursor.insertText(" "); - } - - // Remove indentation. - int idx = 0; - for (idx = 0; idx < textToAppend.size(); ++idx) { - if (!textToAppend[idx].isSpace()) { - break; - } - } - - textToAppend = textToAppend.right(textToAppend.size() - idx); - } - - // Now p_cursor is at the end of the first block. - int position = p_cursor.block().position() + p_cursor.positionInBlock(); - p_cursor.insertText(textToAppend); - - // Delete the second block. - p_cursor.movePosition(QTextCursor::NextBlock); - VEditUtils::removeBlock(p_cursor); - - // Position p_cursor right at the front of appended text. - p_cursor.setPosition(position); -} - -// Join lines specified by [@p_firstBlock, @p_firstBlock + p_blockCount). -// Need to check the block range (based on 0). -static bool joinLines(QTextCursor &p_cursor, - int p_firstBlock, - int p_blockCount, - bool p_modifySpaces) -{ - QTextDocument *doc = p_cursor.document(); - int totalBlockCount = doc->blockCount(); - if (p_blockCount <= 0 - || p_firstBlock >= totalBlockCount - 1) { - return false; - } - - p_blockCount = qMin(p_blockCount, totalBlockCount - p_firstBlock); - p_cursor.setPosition(doc->findBlockByNumber(p_firstBlock).position()); - for (int i = 1; i < p_blockCount; ++i) { - joinTwoLines(p_cursor, p_modifySpaces); - } - - return true; -} - -bool VVim::handleKeyPressEvent(QKeyEvent *p_event, int *p_autoIndentPos) -{ - bool ret = handleKeyPressEvent(p_event->key(), p_event->modifiers(), p_autoIndentPos); - if (ret) { - p_event->accept(); - } - - return ret; -} - -bool VVim::handleKeyPressEvent(int key, int modifiers, int *p_autoIndentPos) -{ - bool ret = false; - bool resetPositionInBlock = true; - Key keyInfo(key, modifiers); - bool unindent = false; - int autoIndentPos = p_autoIndentPos ? *p_autoIndentPos : -1; - - // Handle Insert mode key press. - if (VimMode::Insert == m_mode) { - if (key == Qt::Key_Escape - || (key == Qt::Key_BracketLeft && VUtils::isControlModifierForVim(modifiers))) { - // See if we need to cancel auto indent. - bool cancelAutoIndent = false; - if (p_autoIndentPos && *p_autoIndentPos > -1) { - QTextCursor cursor = m_editor->textCursorW(); - cancelAutoIndent = VEditUtils::needToCancelAutoIndent(*p_autoIndentPos, cursor); - - if (cancelAutoIndent) { - autoIndentPos = -1; - VEditUtils::deleteIndentAndListMark(cursor); - m_editor->setTextCursorW(cursor); - } - } - - // Clear selection and enter Normal mode. - if (!cancelAutoIndent) { - clearSelection(); - } - - setMode(VimMode::Normal); - goto clear_accept; - } - - if (m_registerPending) { - // Ctrl and Shift may be sent out first. - if (key == Qt::Key_Control || key == Qt::Key_Shift || key == Qt::Key_Meta) { - goto accept; - } - - // Expecting a register name. - QChar reg = keyToRegisterName(keyInfo); - if (!reg.isNull()) { - // Insert register content. - m_editor->insertPlainTextW(getRegister(reg).read()); - } - - goto clear_accept; - } else if (key == Qt::Key_R && VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+R, insert the content of a register. - m_pendingKeys.append(keyInfo); - m_registerPending = true; - goto accept; - } - - if (key == Qt::Key_O && VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+O, enter normal mode, execute one command, then return to insert mode. - m_insertModeAfterCommand = true; - clearSelection(); - setMode(VimMode::Normal); - goto accept; - } - - // Let it be handled outside VVim. - goto exit; - } - - // Ctrl and Shift may be sent out first. - if (key == Qt::Key_Control || key == Qt::Key_Shift || key == Qt::Key_Meta) { - goto accept; - } - - if (m_replayLeaderSequence) { - qDebug() << "replaying sequence" << keyToChar(key, modifiers); - } - - m_pendingKeys.append(keyInfo); - - if (expectingLeaderSequence()) { - if (processLeaderSequence(keyInfo)) { - goto accept; - } else { - goto clear_accept; - } - } - - if (expectingRegisterName()) { - // Expecting a register name. - QChar reg = keyToRegisterName(keyInfo); - if (!reg.isNull()) { - m_keys.clear(); - setCurrentRegisterName(reg); - Register &r = getRegister(reg); - if (r.isNamedRegister()) { - r.m_append = (modifiers == Qt::ShiftModifier); - } else { - Q_ASSERT(!r.m_append); - } - - goto accept; - } - - goto clear_accept; - } - - if (expectingMarkName()) { - // Expecting a mark name to create a mark. - if (keyInfo.isAlphabet() && modifiers == Qt::NoModifier) { - m_keys.clear(); - m_marks.setMark(keyToChar(key, modifiers), m_editor->textCursorW()); - } - - goto clear_accept; - } - - if (expectingMarkTarget()) { - // Expecting a mark name as the target. - Movement mm = Movement::Invalid; - const Key &aKey = m_keys.first(); - if (aKey == Key(Qt::Key_Apostrophe)) { - mm = Movement::MarkJumpLine; - } else { - Q_ASSERT(aKey == Key(Qt::Key_QuoteLeft)); - mm = Movement::MarkJump; - } - - tryAddMoveAction(); - addMovementToken(mm, keyInfo); - processCommand(m_tokens); - goto clear_accept; - } - - if (expectingCharacterTarget()) { - // Expecting a target character for f/F/t/T. - Movement mm = Movement::Invalid; - const Key &aKey = m_keys.first(); - if (aKey.m_key == Qt::Key_F) { - if (aKey.m_modifiers == Qt::NoModifier) { - mm = Movement::FindForward; - } else { - mm = Movement::FindBackward; - } - } else { - if (aKey.m_modifiers == Qt::NoModifier) { - mm = Movement::TillForward; - } else { - mm = Movement::TillBackward; - } - } - - tryAddMoveAction(); - addMovementToken(mm, keyInfo); - m_lastFindToken = m_tokens.last(); - processCommand(m_tokens); - - goto clear_accept; - } - - if (expectingReplaceCharacter()) { - // Expecting a character to replace with for r. - addActionToken(Action::Replace); - addKeyToken(keyInfo); - processCommand(m_tokens); - - goto clear_accept; - } - - // Check leader key here. If leader key conflicts with other keys, it will - // overwrite it. - // Leader sequence is just like an action. - if (keyInfo == m_leaderKey - && !hasActionToken() - && !hasNonDigitPendingKeys() - && !m_replayLeaderSequence) { - tryGetRepeatToken(m_keys, m_tokens); - - Q_ASSERT(m_keys.isEmpty()); - - m_pendingKeys.pop_back(); - m_pendingKeys.append(Key(Qt::Key_Backslash)); - m_keys.append(Key(Qt::Key_Backslash)); - goto accept; - } - - // We will add key to m_keys. If all m_keys can combined to a token, add - // a new token to m_tokens, clear m_keys and try to process m_tokens. - switch (key) { - case Qt::Key_0: - { - if (modifiers == Qt::NoModifier - || modifiers == Qt::KeypadModifier) { - if (checkPendingKey(Key(Qt::Key_G))) { - // StartOfVisualLine. - tryAddMoveAction(); - m_tokens.append(Token(Movement::StartOfVisualLine)); - processCommand(m_tokens); - } else if (m_keys.isEmpty()) { - // StartOfLine. - tryAddMoveAction(); - m_tokens.append(Token(Movement::StartOfLine)); - processCommand(m_tokens); - } else if (m_keys.last().isDigit()) { - // Repeat. - m_keys.append(keyInfo); - resetPositionInBlock = false; - goto accept; - } - } - - break; - } - - case Qt::Key_1: - case Qt::Key_2: - case Qt::Key_3: - case Qt::Key_4: - case Qt::Key_5: - case Qt::Key_6: - case Qt::Key_7: - case Qt::Key_8: - case Qt::Key_9: - { - if (modifiers == Qt::NoModifier - || modifiers == Qt::KeypadModifier) { - if (!m_keys.isEmpty() && numberFromKeySequence(m_keys) == -1) { - // Invalid sequence. - break; - } - - m_keys.append(keyInfo); - resetPositionInBlock = false; - goto accept; - } - - break; - } - - case Qt::Key_Left: - case Qt::Key_Down: - case Qt::Key_Up: - case Qt::Key_Right: - case Qt::Key_H: - case Qt::Key_J: - case Qt::Key_K: - case Qt::Key_L: - { - if (modifiers == Qt::NoModifier || modifiers == Qt::KeypadModifier) { - // Check if we could generate a Repeat token. - tryGetRepeatToken(m_keys, m_tokens); - - // Generate a Movement token. - Movement mm = Movement::Invalid; - - if (!m_keys.isEmpty()) { - // gj, gk. - Key gKey(Qt::Key_G); - if (m_keys.size() == 1 && m_keys.at(0) == gKey) { - if (key == Qt::Key_J) { - mm = Movement::VisualDown; - } else if (key == Qt::Key_K) { - mm = Movement::VisualUp; - } else { - break; - } - } else { - // Not a valid sequence. - break; - } - } else { - // h, j, k, l. - switch (key) { - case Qt::Key_H: - case Qt::Key_Left: - mm = Movement::Left; - break; - - case Qt::Key_L: - case Qt::Key_Right: - mm = Movement::Right; - break; - - case Qt::Key_J: - case Qt::Key_Down: - mm = Movement::Down; - break; - - case Qt::Key_K: - case Qt::Key_Up: - mm = Movement::Up; - break; - - default: - V_ASSERT(false); - } - } - - V_ASSERT(mm != Movement::Invalid); - tryAddMoveAction(); - addMovementToken(mm); - processCommand(m_tokens); - resetPositionInBlock = false; - } else if (modifiers == Qt::ShiftModifier) { - if (key == Qt::Key_J) { - tryGetRepeatToken(m_keys, m_tokens); - - if (hasActionToken()) { - break; - } - - if (checkPendingKey(Key(Qt::Key_G))) { - // gJ, JoinNoModification. - addActionToken(Action::JoinNoModification); - } else if (m_keys.isEmpty()) { - // J, Join. - addActionToken(Action::Join); - } - - processCommand(m_tokens); - } - } - - break; - } - - case Qt::Key_I: - { - if (modifiers == Qt::NoModifier) { - if (hasActionTokenValidForTextObject()) { - // Inner text object. - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty()) { - // Invalid sequence; - break; - } - - m_keys.append(keyInfo); - goto accept; - } - - // Enter Insert mode. - // Different from Vim: - // We enter Insert mode even in Visual and VisualLine mode. We - // also keep the selection after the mode change. - if (checkMode(VimMode::Normal) - || checkMode(VimMode::Visual) - || checkMode(VimMode::VisualLine)) { - setMode(VimMode::Insert, false); - } - } else if (modifiers == Qt::ShiftModifier) { - QTextCursor cursor = m_editor->textCursorW(); - if (m_mode == VimMode::Normal) { - // Insert at the first non-space character. - VEditUtils::moveCursorFirstNonSpaceCharacter(cursor, QTextCursor::MoveAnchor); - } else if (m_mode == VimMode::Visual || m_mode == VimMode::VisualLine) { - // Insert at the start of line. - cursor.movePosition(QTextCursor::StartOfBlock, - QTextCursor::MoveAnchor, - 1); - } - - m_editor->setTextCursorW(cursor); - setMode(VimMode::Insert); - } else if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+I, jump to next location. - if (!m_tokens.isEmpty() - || !checkMode(VimMode::Normal)) { - break; - } - - tryGetRepeatToken(m_keys, m_tokens); - - if (!m_keys.isEmpty()) { - break; - } - - addActionToken(Action::JumpNextLocation); - processCommand(m_tokens); - break; - } - - break; - } - - case Qt::Key_A: - { - if (modifiers == Qt::NoModifier) { - if (hasActionTokenValidForTextObject()) { - // Around text object. - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty()) { - // Invalid sequence; - break; - } - - m_keys.append(keyInfo); - goto accept; - } - - // Enter Insert mode. - // Move cursor back one character. - if (m_mode == VimMode::Normal) { - QTextCursor cursor = m_editor->textCursorW(); - V_ASSERT(!cursor.hasSelection()); - - if (!cursor.atBlockEnd()) { - cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1); - m_editor->setTextCursorW(cursor); - } - - setMode(VimMode::Insert); - } - } else if (modifiers == Qt::ShiftModifier) { - // Insert at the end of line. - QTextCursor cursor = m_editor->textCursorW(); - if (m_mode == VimMode::Normal) { - cursor.movePosition(QTextCursor::EndOfBlock, - QTextCursor::MoveAnchor, - 1); - m_editor->setTextCursorW(cursor); - } else if (m_mode == VimMode::Visual || m_mode == VimMode::VisualLine) { - if (!cursor.atBlockEnd()) { - cursor.clearSelection(); - cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1); - m_editor->setTextCursorW(cursor); - } - } - - setMode(VimMode::Insert); - } - - break; - } - - case Qt::Key_O: - { - if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier) { - // Insert a new block under/above current block and enter insert mode. - bool insertAbove = modifiers == Qt::ShiftModifier; - if (m_mode == VimMode::Normal) { - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - cursor.movePosition(insertAbove ? QTextCursor::StartOfBlock - : QTextCursor::EndOfBlock, - QTextCursor::MoveAnchor, - 1); - - cursor.insertBlock(); - - if (insertAbove) { - cursor.movePosition(QTextCursor::PreviousBlock, - QTextCursor::MoveAnchor, - 1); - } - - bool textInserted = false; - if (g_config->getAutoIndent()) { - textInserted = VEditUtils::indentBlockAsBlock(cursor, false); - if (g_config->getAutoList()) { - textInserted = VEditUtils::insertListMarkAsPreviousBlock(cursor) - || textInserted; - } - } - - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); - - if (textInserted) { - autoIndentPos = cursor.position(); - } - - setMode(VimMode::Insert); - } - - break; - } else if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+O, jump to previous location. - if (!m_tokens.isEmpty() - || !checkMode(VimMode::Normal)) { - break; - } - - tryGetRepeatToken(m_keys, m_tokens); - - if (!m_keys.isEmpty()) { - break; - } - - addActionToken(Action::JumpPreviousLocation); - processCommand(m_tokens); - break; - } - - break; - } - - case Qt::Key_S: - { - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty() || hasActionToken()) { - break; - } - - if (modifiers == Qt::NoModifier) { - addActionToken(Action::Change); - // Movement will be ignored in Visual mode. - addMovementToken(Movement::Right); - processCommand(m_tokens); - } else if (modifiers == Qt::ShiftModifier) { - // S, change current line. - addActionToken(Action::Change); - addRangeToken(Range::Line); - processCommand(m_tokens); - } - - break; - } - - case Qt::Key_Dollar: - { - if (modifiers == Qt::ShiftModifier) { - // $, move to end of line. - tryGetRepeatToken(m_keys, m_tokens); - - if (m_keys.isEmpty()) { - tryAddMoveAction(); - - m_tokens.append(Token(Movement::EndOfLine)); - processCommand(m_tokens); - } - } - - break; - } - - case Qt::Key_G: - { - Movement mm = Movement::Invalid; - if (modifiers == Qt::NoModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (m_keys.isEmpty()) { - // First g, pend it. - m_keys.append(keyInfo); - goto accept; - } else if (m_keys.size() == 1 && m_keys.at(0) == keyInfo) { - // gg, go to a certain line or first line. - if (!m_tokens.isEmpty() && m_tokens.last().isRepeat()) { - mm = Movement::LineJump; - } else { - mm = Movement::StartOfDocument; - } - } - } else if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (m_keys.isEmpty()) { - // G, go to a certain line or the last line. - if (!m_tokens.isEmpty() && m_tokens.last().isRepeat()) { - mm = Movement::LineJump; - } else { - mm = Movement::EndOfDocument; - } - } - } - - if (mm != Movement::Invalid) { - tryAddMoveAction(); - - m_tokens.append(Token(mm)); - processCommand(m_tokens); - } - - break; - } - - // Should be kept together with Qt::Key_PageUp. - case Qt::Key_B: - { - if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+B, page up, fall through. - modifiers = Qt::NoModifier; - } else if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty()) { - if (modifiers == Qt::NoModifier && checkPendingKey(Key(Qt::Key_Z))) { - // zb, redraw to make a certain line the bottom of window. - addActionToken(Action::RedrawAtBottom); - processCommand(m_tokens); - break; - } - - break; - } - - // b, go to the start of previous or current word. - Movement mm = Movement::WordBackward; - if (modifiers == Qt::ShiftModifier) { - // B, go to the start of previous or current WORD. - mm = Movement::WORDBackward; - } - - tryAddMoveAction(); - m_tokens.append(Token(mm)); - processCommand(m_tokens); - break; - } else { - break; - } - - V_FALLTHROUGH; - } - - case Qt::Key_PageUp: - { - if (modifiers == Qt::NoModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty()) { - // Not a valid sequence. - break; - } - - Movement mm = Movement::PageUp; - tryAddMoveAction(); - m_tokens.append(Token(mm)); - processCommand(m_tokens); - resetPositionInBlock = false; - } - - break; - } - - case Qt::Key_U: - { - tryGetRepeatToken(m_keys, m_tokens); - bool toLower = modifiers == Qt::NoModifier; - - if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+U, HalfPageUp. - if (!m_keys.isEmpty()) { - // Not a valid sequence. - break; - } - - Movement mm = Movement::HalfPageUp; - tryAddMoveAction(); - m_tokens.append(Token(mm)); - processCommand(m_tokens); - resetPositionInBlock = false; - } else if (m_keys.isEmpty() && !hasActionToken()) { - if (m_mode == VimMode::Visual || m_mode == VimMode::VisualLine) { - // u/U for tolower and toupper selected text. - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - // Different from Vim: - // If there is no selection in Visual mode, we do nothing. - if (m_mode == VimMode::VisualLine) { - int nrBlock = VEditUtils::selectedBlockCount(cursor); - message(tr("%1 %2 changed").arg(nrBlock).arg(nrBlock > 1 ? tr("lines") - : tr("line"))); - } - - convertCaseOfSelectedText(cursor, toLower); - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); - - setMode(VimMode::Normal); - break; - } - - // u, Undo. - if (modifiers == Qt::NoModifier) { - addActionToken(Action::Undo); - processCommand(m_tokens); - } - break; - } else { - if (hasActionToken()) { - // guu/gUU. - if ((toLower && checkActionToken(Action::ToLower)) - || (!toLower && checkActionToken(Action::ToUpper))) { - addRangeToken(Range::Line); - processCommand(m_tokens); - break; - } else { - // An invalid sequence. - break; - } - } else if (checkPendingKey(Key(Qt::Key_G))) { - // gu/gU, ToLower/ToUpper action. - if (m_mode == VimMode::Visual || m_mode == VimMode::VisualLine) { - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - // Different from Vim: - // If there is no selection in Visual mode, we do nothing. - if (m_mode == VimMode::VisualLine) { - int nrBlock = VEditUtils::selectedBlockCount(cursor); - message(tr("%1 %2 changed").arg(nrBlock).arg(nrBlock > 1 ? tr("lines") - : tr("line"))); - } - - convertCaseOfSelectedText(cursor, toLower); - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); - setMode(VimMode::Normal); - break; - } - - addActionToken(toLower ? Action::ToLower : Action::ToUpper); - m_keys.clear(); - goto accept; - } else { - // An invalid sequence. - break; - } - } - - break; - } - - // Ctrl+F is used for Find dialog, not used here. - case Qt::Key_PageDown: - { - if (modifiers == Qt::NoModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty()) { - // Not a valid sequence. - break; - } - - Movement mm = Movement::PageDown; - tryAddMoveAction(); - m_tokens.append(Token(mm)); - processCommand(m_tokens); - resetPositionInBlock = false; - } - - break; - } - - case Qt::Key_D: - { - if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+D, HalfPageDown. - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty()) { - // Not a valid sequence. - break; - } - - Movement mm = Movement::HalfPageDown; - tryAddMoveAction(); - m_tokens.append(Token(mm)); - processCommand(m_tokens); - resetPositionInBlock = false; - } else if (modifiers == Qt::NoModifier) { - // d, delete action. - tryGetRepeatToken(m_keys, m_tokens); - if (hasActionToken()) { - // This is another d, something like dd. - if (checkActionToken(Action::Delete)) { - addRangeToken(Range::Line); - processCommand(m_tokens); - break; - } else { - // An invalid sequence. - break; - } - } else { - // The first d, an Action. - addActionToken(Action::Delete); - if (checkMode(VimMode::Visual) || checkMode(VimMode::VisualLine)) { - // Movement will be ignored. - addMovementToken(Movement::Left); - processCommand(m_tokens); - setMode(VimMode::Normal); - break; - } - - goto accept; - } - } else if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (!hasActionToken()) { - if (checkMode(VimMode::Normal)) { - // D, same as d$. - addActionToken(Action::Delete); - addMovementToken(Movement::EndOfLine); - processCommand(m_tokens); - } else if (checkMode(VimMode::Visual) || checkMode(VimMode::VisualLine)) { - // D, same as dd. - addActionToken(Action::Delete); - addRangeToken(Range::Line); - processCommand(m_tokens); - setMode(VimMode::Normal); - } - } - - break; - } - - break; - } - - case Qt::Key_BracketRight: - { - if (modifiers == Qt::NoModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // BracketInner/BracketAround. - Range range = Range::BracketInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::BracketAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } else if (hasActionToken() || !checkMode(VimMode::Normal)) { - // Invalid sequence. - break; - } else if (m_keys.isEmpty()) { - // First ], pend it. - m_keys.append(keyInfo); - goto accept; - } else if (checkPendingKey(keyInfo)) { - // ]], goto next title, regardless of level. - processTitleJump(m_tokens, true, 1); - } else if (checkPendingKey(Key(Qt::Key_BracketLeft))) { - // [], goto previous title at the same level. - processTitleJump(m_tokens, false, 0); - } - - break; - } - - break; - } - - // Should be kept together with Qt::Key_Escape. - case Qt::Key_BracketLeft: - { - if (VUtils::isControlModifierForVim(modifiers)) { - // fallthrough. - } else if (modifiers == Qt::NoModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // BracketInner/BracketAround. - Range range = Range::BracketInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::BracketAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } else if (hasActionToken() || !checkMode(VimMode::Normal)) { - // Invalid sequence. - break; - } else if (m_keys.isEmpty()) { - // First [, pend it. - m_keys.append(keyInfo); - goto accept; - } else if (checkPendingKey(keyInfo)) { - // [[, goto previous title, regardless of level. - processTitleJump(m_tokens, false, 1); - } else if (checkPendingKey(Key(Qt::Key_BracketRight))) { - // ][, goto next title at the same level. - processTitleJump(m_tokens, true, 0); - } - - break; - } else { - break; - } - - V_FALLTHROUGH; - } - - case Qt::Key_Escape: - { - // Clear selection and enter normal mode. - int position = -1; - if (checkMode(VimMode::Visual)) { - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.position() > cursor.anchor()) { - position = cursor.position() - 1; - } - } - - bool ret = clearSelection(); - if (!ret && checkMode(VimMode::Normal)) { - emit m_editor->object()->requestCloseFindReplaceDialog(); - } - - setMode(VimMode::Normal, true, position); - break; - } - - case Qt::Key_V: - { - if (modifiers == Qt::NoModifier) { - if (checkMode(VimMode::Visual)) { - setMode(VimMode::Normal, true); - } else { - // Toggle Visual Mode. - setMode(VimMode::Visual); - maintainSelectionInVisualMode(); - } - } else if (modifiers == Qt::ShiftModifier) { - // Visual Line Mode. - clearSelection(); - VimMode mode = VimMode::VisualLine; - if (m_mode == VimMode::VisualLine) { - mode = VimMode::Normal; - } - - setMode(mode); - - if (m_mode == VimMode::VisualLine) { - QTextCursor cursor = m_editor->textCursorW(); - expandSelectionToWholeLines(cursor); - m_editor->setTextCursorW(cursor); - } - } else if (VUtils::isControlModifierForVim(modifiers)) { - if (g_config->getVimExemptionKeys().contains('v')) { - // Let it be handled outside. - resetState(); - goto exit; - } - } - - break; - } - - case Qt::Key_AsciiCircum: - { - if (modifiers == Qt::ShiftModifier) { - // ~, go to first non-space character of current line (block). - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty()) { - // Not a valid sequence. - break; - } - - Movement mm = Movement::FirstCharacter; - tryAddMoveAction(); - m_tokens.append(Token(mm)); - processCommand(m_tokens); - } - - break; - } - - case Qt::Key_W: - { - if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier) { - bool shift = modifiers == Qt::ShiftModifier; - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // WordInner/WORDInner/WordAournd/WORDAround. - bool around = checkPendingKey(Key(Qt::Key_A)); - Range range = Range::Invalid; - if (shift) { - if (around) { - range = Range::WORDAround; - } else { - range = Range::WORDInner; - } - } else { - if (around) { - range = Range::WordAround; - } else { - range = Range::WordInner; - } - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } else if (!m_keys.isEmpty()) { - // Not a valid sequence. - break; - } - - // w, go to the start of next word. - Movement mm = Movement::WordForward; - if (shift) { - // W, go to the start of next WORD. - mm = Movement::WORDForward; - } - - if (checkActionToken(Action::Change)) { - // In Change action, cw equals to ce. - if (shift) { - mm = Movement::ForwardEndOfWORD; - } else { - mm = Movement::ForwardEndOfWord; - } - } else { - tryAddMoveAction(); - } - - addMovementToken(mm); - processCommand(m_tokens); - break; - } - - break; - } - - case Qt::Key_E: - { - // e, E, ge, gE. - if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - Movement mm = Movement::Invalid; - if (!m_keys.isEmpty()) { - if (m_keys.size() == 1 && m_keys.at(0) == Key(Qt::Key_G)) { - // ge, gE. - if (modifiers == Qt::NoModifier) { - mm = Movement::BackwardEndOfWord; - } else { - mm = Movement::BackwardEndOfWORD; - } - } else { - // Not a valid sequence. - break; - } - } else { - // e, E. - if (modifiers == Qt::NoModifier) { - mm = Movement::ForwardEndOfWord; - } else { - mm = Movement::ForwardEndOfWORD; - } - } - - tryAddMoveAction(); - m_tokens.append(Token(mm)); - processCommand(m_tokens); - } - - break; - } - - case Qt::Key_QuoteDbl: - { - if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // DoubleQuoteInner/DoubleQuoteAround. - Range range = Range::DoubleQuoteInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::DoubleQuoteAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } else if (!m_keys.isEmpty() || hasActionToken()) { - // Invalid sequence. - break; - } - - // ", specify a register. - m_keys.append(keyInfo); - goto accept; - } - - break; - } - - case Qt::Key_X: - { - if (modifiers == Qt::ShiftModifier || modifiers == Qt::NoModifier) { - // x, or X to delete one char. - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty() || hasActionToken()) { - break; - } - - addActionToken(Action::Delete); - if (modifiers == Qt::ShiftModifier) { - if (checkMode(VimMode::Visual) || checkMode(VimMode::VisualLine)) { - // X, same as dd. - addRangeToken(Range::Line); - } else { - // X, delete one char. - addMovementToken(Movement::Left); - } - } else { - // x. - // Movement will be ignored in Visual mode. - addMovementToken(Movement::Right); - } - - processCommand(m_tokens); - setMode(VimMode::Normal); - break; - } - - break; - } - - case Qt::Key_Y: - { - if (modifiers == Qt::NoModifier) { - // y, copy action. - tryGetRepeatToken(m_keys, m_tokens); - if (hasActionToken()) { - // This is another y, something like yy. - if (checkActionToken(Action::Copy) && checkMode(VimMode::Normal)) { - addRangeToken(Range::Line); - processCommand(m_tokens); - } else { - // An invalid sequence. - break; - } - } else { - // The first y, an Action. - if (m_mode == VimMode::Visual || m_mode == VimMode::VisualLine) { - copySelectedText(m_mode == VimMode::VisualLine); - setMode(VimMode::Normal); - break; - } - - addActionToken(Action::Copy); - goto accept; - } - } else if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (!hasActionToken()) { - // Y, same as yy. - addActionToken(Action::Copy); - addRangeToken(Range::Line); - processCommand(m_tokens); - setMode(VimMode::Normal); - } - - break; - } - - break; - } - - case Qt::Key_P: - { - if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier) { - // p/P, paste/pastebefore action. - tryGetRepeatToken(m_keys, m_tokens); - if (hasActionToken() || !m_keys.isEmpty()) { - // An invalid sequence. - break; - } - - addActionToken(modifiers == Qt::NoModifier ? Action::Paste - : Action::PasteBefore); - processCommand(m_tokens); - break; - } - - break; - } - - case Qt::Key_C: - { - if (modifiers == Qt::NoModifier) { - // c, change action. - tryGetRepeatToken(m_keys, m_tokens); - if (hasActionToken()) { - // This is another c, something like cc. - if (checkActionToken(Action::Change)) { - addRangeToken(Range::Line); - processCommand(m_tokens); - break; - } else { - // An invalid sequence. - break; - } - } else { - // The first c, an action. - addActionToken(Action::Change); - - if (checkMode(VimMode::VisualLine) || checkMode(VimMode::Visual)) { - // Movement will be ignored. - addMovementToken(Movement::Left); - processCommand(m_tokens); - break; - } - - goto accept; - } - } else if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (!hasActionToken() && m_mode == VimMode::Normal) { - // C, same as c$. - addActionToken(Action::Change); - addMovementToken(Movement::EndOfLine); - processCommand(m_tokens); - } - - break; - } else if (VUtils::isControlModifierForVim(modifiers)) { - if (g_config->getVimExemptionKeys().contains('c')) { - // Let it be handled outside. - resetState(); - goto exit; - } - } - - break; - } - - case Qt::Key_Less: - unindent = true; - // Fall through. - case Qt::Key_Greater: - { - if (modifiers == Qt::ShiftModifier) { - // >/<, Indent/Unindent. - tryGetRepeatToken(m_keys, m_tokens); - if (hasActionToken()) { - // This is another >/<, something like >>/<<. - if ((!unindent && checkActionToken(Action::Indent)) - || (unindent && checkActionToken(Action::UnIndent))) { - addRangeToken(Range::Line); - processCommand(m_tokens); - break; - } else if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // AngleBracketInner/AngleBracketAround. - Range range = Range::AngleBracketInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::AngleBracketAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } - } else { - // The first >/<, an Action. - addActionToken(unindent ? Action::UnIndent : Action::Indent); - - if (checkMode(VimMode::Visual) - || checkMode(VimMode::VisualLine)) { - // Movement will be ignored. - addMovementToken(Movement::Left); - processCommand(m_tokens); - break; - } - - goto accept; - } - } - - break; - } - - case Qt::Key_Equal: - { - if (modifiers == Qt::NoModifier) { - // =, AutoIndent. - tryGetRepeatToken(m_keys, m_tokens); - if (hasActionToken()) { - // ==. - if (checkActionToken(Action::AutoIndent)) { - addRangeToken(Range::Line); - processCommand(m_tokens); - break; - } - } else { - // The first =, an Action. - addActionToken(Action::AutoIndent); - - if (checkMode(VimMode::Visual) - || checkMode(VimMode::VisualLine)) { - // Movement will be ignored. - addMovementToken(Movement::Left); - processCommand(m_tokens); - break; - } - - goto accept; - } - } - - break; - } - - case Qt::Key_F: - { - if (m_mode == VimMode::VisualLine) { - break; - } - - if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier) { - // f/F, find forward/backward within a block. - tryGetRepeatToken(m_keys, m_tokens); - - if (m_keys.isEmpty()) { - m_keys.append(keyInfo); - goto accept; - } - - break; - } - - break; - } - - case Qt::Key_T: - { - if (m_mode == VimMode::VisualLine) { - break; - } - - if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier) { - // t/T, find till forward/backward within a block. - tryGetRepeatToken(m_keys, m_tokens); - - if (m_keys.isEmpty()) { - m_keys.append(keyInfo); - goto accept; - } else if (modifiers == Qt::NoModifier && checkPendingKey(Key(Qt::Key_Z))) { - // zt, redraw to make a certain line the top of window. - addActionToken(Action::RedrawAtTop); - processCommand(m_tokens); - break; - } - - break; - } - - break; - } - - case Qt::Key_Comma: - { - if (m_mode == VimMode::VisualLine) { - break; - } - - // ,, repeat last find target movement, but reversely. - tryGetRepeatToken(m_keys, m_tokens); - - if (m_keys.isEmpty()) { - repeatLastFindMovement(true); - break; - } - - break; - } - - case Qt::Key_Semicolon: - { - if (m_mode == VimMode::VisualLine) { - break; - } - - // ;, repeat last find target movement. - tryGetRepeatToken(m_keys, m_tokens); - - if (m_keys.isEmpty()) { - repeatLastFindMovement(false); - break; - } - - break; - } - - case Qt::Key_R: - { - if (m_mode == VimMode::VisualLine) { - break; - } - - if (VUtils::isControlModifierForVim(modifiers)) { - // Redo. - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty() || hasActionToken()) { - break; - } - - addActionToken(Action::Redo); - processCommand(m_tokens); - break; - } else if (modifiers == Qt::NoModifier) { - // r, replace. - tryGetRepeatToken(m_keys, m_tokens); - if (m_keys.isEmpty() && !hasActionToken()) { - m_keys.append(keyInfo); - goto accept; - } - } - - break; - } - - case Qt::Key_Z: - { - if (modifiers == Qt::NoModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (m_keys.isEmpty() && !hasActionToken()) { - // First z, pend it. - m_keys.append(keyInfo); - goto accept; - } else if (checkPendingKey(keyInfo)) { - // zz, redraw to make a certain line the center of the window. - addActionToken(Action::RedrawAtCenter); - processCommand(m_tokens); - break; - } - - break; - } - - break; - } - - case Qt::Key_Colon: - { - if (modifiers == Qt::ShiftModifier) { - if (m_keys.isEmpty() - && m_tokens.isEmpty() - && checkMode(VimMode::Normal)) { - emit commandLineTriggered(CommandLineType::Command); - } - } - - break; - } - - case Qt::Key_Percent: - { - if (modifiers == Qt::ShiftModifier) { - if (m_keys.isEmpty()) { - // %, FindPair movement. - tryAddMoveAction(); - addMovementToken(Movement::FindPair); - processCommand(m_tokens); - break; - } else { - tryGetRepeatToken(m_keys, m_tokens); - if (m_keys.isEmpty() && hasRepeatToken()) { - // xx%, jump to a certain line (percentage of the documents). - // Change the repeat from percentage to line number. - Token *token = getRepeatToken(); - int bn = percentageToBlockNumber(m_editor->documentW(), token->m_repeat); - if (bn == -1) { - break; - } else { - // Repeat of LineJump is based on 1. - token->m_repeat = bn + 1; - } - - tryAddMoveAction(); - addMovementToken(Movement::LineJump); - processCommand(m_tokens); - break; - } - } - - break; - } - - break; - } - - case Qt::Key_M: - { - if (modifiers == Qt::NoModifier) { - if (m_keys.isEmpty() && m_tokens.isEmpty()) { - // m, creating a mark. - // We can create marks in Visual mode, too. - m_keys.append(keyInfo); - goto accept; - } - } - - break; - } - - case Qt::Key_Apostrophe: - { - if (modifiers == Qt::NoModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // QuoteInner/QuoteAround. - Range range = Range::QuoteInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::QuoteAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } - - // ', jump to the start of line of a mark. - // Repeat is useless in this case. - if (m_keys.isEmpty()) { - m_keys.append(keyInfo); - goto accept; - } - } - - break; - } - - case Qt::Key_QuoteLeft: - { - if (modifiers == Qt::NoModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // BackQuoteInner/BackQuoteAround. - Range range = Range::BackQuoteInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::BackQuoteAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } - - // `, jump to a mark. - // Repeat is useless in this case. - if (m_keys.isEmpty()) { - m_keys.append(keyInfo); - goto accept; - } - } - - break; - } - - case Qt::Key_ParenLeft: - // Fall through. - case Qt::Key_ParenRight: - { - if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // ParenthesisInner/ParenthesisAround. - Range range = Range::ParenthesisInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::ParenthesisAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } - } - - break; - } - - case Qt::Key_BraceLeft: - { - if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // BraceInner/BraceAround. - Range range = Range::BraceInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::BraceAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } else if (m_keys.isEmpty()) { - // {, ParagraphUp movement. - tryAddMoveAction(); - addMovementToken(Movement::ParagraphUp); - processCommand(m_tokens); - } else if (!hasActionToken() - && checkPendingKey(Key(Qt::Key_BracketLeft))) { - // [{, goto previous title at one higher level. - if (checkMode(VimMode::Normal)) { - processTitleJump(m_tokens, false, -1); - } - } - - break; - } - - break; - } - - case Qt::Key_BraceRight: - { - if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // BraceInner/BraceAround. - Range range = Range::BraceInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::BraceAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } else if (m_keys.isEmpty()) { - // }, ParagraphDown movement. - tryAddMoveAction(); - addMovementToken(Movement::ParagraphDown); - processCommand(m_tokens); - } else if (!hasActionToken() - && checkPendingKey(Key(Qt::Key_BracketRight))) { - // ]}, goto next title at one higher level. - if (checkMode(VimMode::Normal)) { - processTitleJump(m_tokens, true, -1); - } - } - - break; - } - - break; - } - - case Qt::Key_AsciiTilde: - { - if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (hasActionToken() || !m_keys.isEmpty()) { - break; - } - - // Reverse the case. - addActionToken(Action::ReverseCase); - processCommand(m_tokens); - - break; - } - - break; - } - - case Qt::Key_Slash: - { - if (modifiers == Qt::NoModifier) { - if (m_tokens.isEmpty() - && m_keys.isEmpty() - && checkMode(VimMode::Normal)) { - emit commandLineTriggered(CommandLineType::SearchForward); - } - } - - break; - } - - case Qt::Key_Question: - { - if (modifiers == Qt::ShiftModifier) { - if (m_tokens.isEmpty() - && m_keys.isEmpty() - && checkMode(VimMode::Normal)) { - emit commandLineTriggered(CommandLineType::SearchBackward); - } - } - - break; - } - - case Qt::Key_N: - { - if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier) { - // n, FindNext/FindPrevious movement. - tryGetRepeatToken(m_keys, m_tokens); - - if (!m_keys.isEmpty()) { - break; - } - - Movement mm = Movement::FindNext; - if (modifiers == Qt::ShiftModifier) { - mm = Movement::FindPrevious; - } - - tryAddMoveAction(); - addMovementToken(mm); - processCommand(m_tokens); - } - - break; - } - - case Qt::Key_Asterisk: - { - if (modifiers == Qt::ShiftModifier) { - // *, FindNextWordUnderCursor movement. - tryGetRepeatToken(m_keys, m_tokens); - - if (!m_keys.isEmpty()) { - break; - } - - tryAddMoveAction(); - addMovementToken(Movement::FindNextWordUnderCursor); - processCommand(m_tokens); - } - - break; - } - - case Qt::Key_NumberSign: - { - if (modifiers == Qt::ShiftModifier) { - // #, FindPreviousWordUnderCursor movement. - tryGetRepeatToken(m_keys, m_tokens); - - if (!m_keys.isEmpty()) { - break; - } - - tryAddMoveAction(); - addMovementToken(Movement::FindPreviousWordUnderCursor); - processCommand(m_tokens); - } - - break; - } - - default: - break; - } - -clear_accept: - resetState(); - - amendCursorPosition(); - - if (m_insertModeAfterCommand - && !checkMode(VimMode::Visual) - && !checkMode(VimMode::VisualLine)) { - m_insertModeAfterCommand = false; - setMode(VimMode::Insert); - } - - m_editor->makeBlockVisible(m_editor->textCursorW().block()); - -accept: - ret = true; - - // Only alter the autoIndentPos when the key is handled by Vim. - if (p_autoIndentPos) { - *p_autoIndentPos = autoIndentPos; - } - -exit: - m_resetPositionInBlock = resetPositionInBlock; - emit vimStatusUpdated(this); - return ret; -} - -void VVim::resetState() -{ - m_keys.clear(); - m_tokens.clear(); - m_pendingKeys.clear(); - setCurrentRegisterName(c_unnamedRegister); - m_resetPositionInBlock = true; - m_registerPending = false; -} - -VimMode VVim::getMode() const -{ - return m_mode; -} - -void VVim::setMode(VimMode p_mode, bool p_clearSelection, int p_position) -{ - if (m_mode != p_mode) { - QTextCursor cursor = m_editor->textCursorW(); - int position = p_position; - if (position == -1) { - if (m_mode == VimMode::Visual - && p_mode == VimMode::Normal - && cursor.position() > cursor.anchor()) { - position = cursor.position() - 1; - } else if (m_mode == VimMode::Insert - && p_mode == VimMode::Normal - && !cursor.atBlockStart()) { - position = cursor.position() - 1; - if (position < 0) { - position = 0; - } - } - } - - if (p_clearSelection) { - clearSelection(); - } - - if (p_mode == VimMode::Insert) { - m_editor->setInputMethodEnabled(true); - } else if (g_config->getEnableSmartImInVimMode()) { - m_editor->setInputMethodEnabled(false); - } - - m_mode = p_mode; - resetState(); - - VMdEditor *mdEditor = dynamic_cast(m_editor); - switch (m_mode) { - case VimMode::Insert: - setCursorBlockMode(m_editor, CursorBlock::None); - if (mdEditor) { - mdEditor->setHighlightCursorLineBlockEnabled(false); - } - - break; - - case VimMode::Visual: - m_positionBeforeVisualMode = cursor.anchor(); - V_FALLTHROUGH; - - default: - setCursorBlockMode(m_editor, CursorBlock::RightSide); - if (mdEditor) { - QString color; - if (m_mode == VimMode::Normal) { - color = g_config->getEditorVimNormalBg(); - } else { - color = g_config->getEditorVimVisualBg(); - } - - mdEditor->setCursorLineBlockBg(color); - mdEditor->setHighlightCursorLineBlockEnabled(true); - } - - break; - } - - if (position != -1) { - cursor.setPosition(position); - m_editor->setTextCursorW(cursor); - } - - amendCursorPosition(); - - emit modeChanged(m_mode); - emit vimStatusUpdated(this); - } -} - -void VVim::processCommand(QList &p_tokens) -{ - if (p_tokens.isEmpty()) { - return; - } - - V_ASSERT(p_tokens.at(0).isAction()); - - Token act = p_tokens.takeFirst(); - switch (act.m_action) { - case Action::Move: - processMoveAction(p_tokens); - break; - - case Action::Delete: - processDeleteAction(p_tokens); - break; - - case Action::Copy: - processCopyAction(p_tokens); - break; - - case Action::Paste: - processPasteAction(p_tokens, false); - break; - - case Action::PasteBefore: - processPasteAction(p_tokens, true); - break; - - case Action::Change: - processChangeAction(p_tokens); - break; - - case Action::Indent: - processIndentAction(p_tokens, IndentType::Indent); - break; - - case Action::UnIndent: - processIndentAction(p_tokens, IndentType::UnIndent); - break; - - case Action::AutoIndent: - processIndentAction(p_tokens, IndentType::AutoIndent); - break; - - case Action::ToLower: - processToLowerAction(p_tokens, true); - break; - - case Action::ToUpper: - processToLowerAction(p_tokens, false); - break; - - case Action::Undo: - processUndoAction(p_tokens); - break; - - case Action::Redo: - processRedoAction(p_tokens); - break; - - case Action::RedrawAtTop: - processRedrawLineAction(p_tokens, 0); - break; - - case Action::RedrawAtCenter: - processRedrawLineAction(p_tokens, 1); - break; - - case Action::RedrawAtBottom: - processRedrawLineAction(p_tokens, 2); - break; - - case Action::JumpPreviousLocation: - processJumpLocationAction(p_tokens, false); - break; - - case Action::JumpNextLocation: - processJumpLocationAction(p_tokens, true); - break; - - case Action::Replace: - processReplaceAction(p_tokens); - break; - - case Action::ReverseCase: - processReverseCaseAction(p_tokens); - break; - - case Action::Join: - processJoinAction(p_tokens, true); - break; - - case Action::JoinNoModification: - processJoinAction(p_tokens, false); - break; - - default: - p_tokens.clear(); - break; - } - - Q_ASSERT(p_tokens.isEmpty()); -} - -int VVim::numberFromKeySequence(const QList &p_keys) -{ - int num = 0; - - for (auto const & key : p_keys) { - if (key.isDigit()) { - num = num * 10 + key.toDigit(); - } else { - return -1; - } - } - - return num == 0 ? -1 : num; -} - -bool VVim::tryGetRepeatToken(QList &p_keys, QList &p_tokens) -{ - if (!p_keys.isEmpty()) { - int repeat = numberFromKeySequence(p_keys); - if (repeat != -1) { - p_tokens.append(Token(repeat)); - p_keys.clear(); - - return true; - } - } - - return false; -} - -void VVim::processMoveAction(QList &p_tokens) -{ - // Only moving left/right could change this. - static int positionInBlock = 0; - - Token to = p_tokens.takeFirst(); - V_ASSERT(to.isRepeat() || to.isMovement()); - Token mvToken; - int repeat = -1; - if (to.isRepeat()) { - repeat = to.m_repeat; - mvToken = p_tokens.takeFirst(); - } else { - mvToken = to; - } - - if (!mvToken.isMovement() || !p_tokens.isEmpty()) { - p_tokens.clear(); - return; - } - - QTextCursor cursor = m_editor->textCursorW(); - if (m_resetPositionInBlock) { - positionInBlock = cursor.positionInBlock(); - } - - QTextCursor::MoveMode moveMode = (m_mode == VimMode::Visual - || m_mode == VimMode::VisualLine) - ? QTextCursor::KeepAnchor - : QTextCursor::MoveAnchor; - bool hasMoved = processMovement(cursor, moveMode, mvToken, repeat); - - if (hasMoved) { - // Maintain positionInBlock. - switch (mvToken.m_movement) { - case Movement::Left: - case Movement::Right: - positionInBlock = cursor.positionInBlock(); - break; - - case Movement::Up: - case Movement::Down: - case Movement::PageUp: - case Movement::PageDown: - case Movement::HalfPageUp: - case Movement::HalfPageDown: - setCursorPositionInBlock(cursor, positionInBlock, moveMode); - break; - - default: - break; - } - - if (checkMode(VimMode::VisualLine)) { - expandSelectionToWholeLines(cursor); - } else if (checkMode(VimMode::Visual)) { - maintainSelectionInVisualMode(&cursor); - } - - m_editor->setTextCursorW(cursor); - } -} - -bool VVim::processMovement(QTextCursor &p_cursor, - QTextCursor::MoveMode p_moveMode, - const Token &p_token, - int p_repeat) -{ - V_ASSERT(p_token.isMovement()); - - bool hasMoved = false; - bool inclusive = true; - bool forward = true; - QTextDocument *doc = p_cursor.document(); - - switch (p_token.m_movement) { - case Movement::Left: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - int pib = p_cursor.positionInBlock(); - p_repeat = qMin(pib, p_repeat); - - if (p_repeat > 0) { - p_cursor.movePosition(QTextCursor::Left, p_moveMode, p_repeat); - hasMoved = true; - } - - break; - } - - case Movement::Right: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - if (checkMode(VimMode::Visual)) { - int pos = p_cursor.position(); - if (pos == p_cursor.anchor() - 1 && pos == m_positionBeforeVisualMode) { - ++p_repeat; - } - } - - int pib = p_cursor.positionInBlock(); - int length = p_cursor.block().length(); - if (length - pib <= p_repeat) { - p_repeat = length - pib - 1; - } - - if (p_repeat > 0) { - p_cursor.movePosition(QTextCursor::Right, p_moveMode, p_repeat); - hasMoved = true; - } - - break; - } - - case Movement::Up: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - p_repeat = qMin(p_cursor.block().blockNumber(), p_repeat); - - if (p_repeat > 0) { - p_cursor.movePosition(QTextCursor::PreviousBlock, p_moveMode, p_repeat); - hasMoved = true; - } - - break; - } - - case Movement::Down: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - int blockCount = doc->blockCount(); - p_repeat = qMin(blockCount - 1 - p_cursor.block().blockNumber(), p_repeat); - - if (p_repeat > 0) { - p_cursor.movePosition(QTextCursor::NextBlock, p_moveMode, p_repeat); - hasMoved = true; - } - - break; - } - - case Movement::VisualUp: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - p_cursor.movePosition(QTextCursor::Up, p_moveMode, p_repeat); - hasMoved = true; - break; - } - - case Movement::VisualDown: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - p_cursor.movePosition(QTextCursor::Down, p_moveMode, p_repeat); - hasMoved = true; - break; - } - - case Movement::PageUp: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - int blockStep = blockCountOfPageStep() * p_repeat; - int block = p_cursor.block().blockNumber(); - block = qMax(0, block - blockStep); - p_cursor.setPosition(doc->findBlockByNumber(block).position(), p_moveMode); - hasMoved = true; - - break; - } - - case Movement::PageDown: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - int blockStep = blockCountOfPageStep() * p_repeat; - int block = p_cursor.block().blockNumber(); - block = qMin(block + blockStep, doc->blockCount() - 1); - p_cursor.setPosition(doc->findBlockByNumber(block).position(), p_moveMode); - hasMoved = true; - - break; - } - - case Movement::HalfPageUp: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - int blockStep = blockCountOfPageStep(); - int halfBlockStep = qMax(blockStep / 2, 1); - blockStep = p_repeat * halfBlockStep; - int block = p_cursor.block().blockNumber(); - block = qMax(0, block - blockStep); - p_cursor.setPosition(doc->findBlockByNumber(block).position(), p_moveMode); - hasMoved = true; - - break; - } - - case Movement::HalfPageDown: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - int blockStep = blockCountOfPageStep(); - int halfBlockStep = qMax(blockStep / 2, 1); - blockStep = p_repeat * halfBlockStep; - int block = p_cursor.block().blockNumber(); - block = qMin(block + blockStep, doc->blockCount() - 1); - p_cursor.setPosition(doc->findBlockByNumber(block).position(), p_moveMode); - hasMoved = true; - - break; - } - - case Movement::StartOfLine: - { - Q_ASSERT(p_repeat == -1); - - // Start of the Line (block). - if (!p_cursor.atBlockStart()) { - p_cursor.movePosition(QTextCursor::StartOfBlock, p_moveMode, 1); - hasMoved = true; - } - - break; - } - - case Movement::StartOfVisualLine: - { - // Start of the visual line. - if (!p_cursor.atBlockStart()) { - p_cursor.movePosition(QTextCursor::StartOfLine, p_moveMode, 1); - hasMoved = true; - } - - break; - } - - case Movement::EndOfLine: - { - // End of line (block). - if (p_repeat == -1) { - p_repeat = 1; - } else if (p_repeat > 1) { - // Move down (p_repeat-1) blocks. - p_cursor.movePosition(QTextCursor::NextBlock, p_moveMode, p_repeat - 1); - } - - // Move to the end of block. - p_cursor.movePosition(QTextCursor::EndOfBlock, p_moveMode, 1); - hasMoved = true; - break; - } - - case Movement::FirstCharacter: - { - // p_repeat is not considered in this command. - // If all the block is space, just move to the end of block; otherwise, - // move to the first non-space character. - VEditUtils::moveCursorFirstNonSpaceCharacter(p_cursor, p_moveMode); - - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } - - case Movement::LineJump: - { - // Jump to the first non-space character of @p_repeat line (block). - V_ASSERT(p_repeat > 0); - - // Record current location. - m_locations.addLocation(p_cursor); - - // @p_repeat starts from 1 while block number starts from 0. - QTextBlock block = doc->findBlockByNumber(p_repeat - 1); - if (block.isValid()) { - p_cursor.setPosition(block.position(), p_moveMode); - } else { - // Go beyond the document. - p_cursor.movePosition(QTextCursor::End, p_moveMode, 1); - } - - VEditUtils::moveCursorFirstNonSpaceCharacter(p_cursor, p_moveMode); - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } - - case Movement::StartOfDocument: - { - // Jump to the first non-space character of the start of the document. - V_ASSERT(p_repeat == -1); - - // Record current location. - m_locations.addLocation(p_cursor); - - p_cursor.movePosition(QTextCursor::Start, p_moveMode, 1); - VEditUtils::moveCursorFirstNonSpaceCharacter(p_cursor, p_moveMode); - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } - - case Movement::EndOfDocument: - { - // Jump to the first non-space character of the end of the document. - V_ASSERT(p_repeat == -1); - - // Record current location. - m_locations.addLocation(p_cursor); - - p_cursor.movePosition(QTextCursor::End, p_moveMode, 1); - VEditUtils::moveCursorFirstNonSpaceCharacter(p_cursor, p_moveMode); - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } - - case Movement::WordForward: - { - // Go to the start of next word. - if (p_repeat == -1) { - p_repeat = 1; - } - - while (p_repeat) { - if (p_cursor.atEnd()) { - break; - } - - p_cursor.movePosition(QTextCursor::NextWord, p_moveMode); - if (p_cursor.atBlockEnd()) { - // dw/yw/cw will stop at the end of the line. - if (p_repeat == 1 - && checkMode(VimMode::Normal) - && p_moveMode == QTextCursor::KeepAnchor) { - --p_repeat; - } - - continue; - } else if (doc->characterAt(p_cursor.position()).isSpace() - || VEditUtils::isSpaceBlock(p_cursor.block())) { - continue; - } - - --p_repeat; - } - - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } - - case Movement::WORDForward: - { - // Go to the start of next WORD. - if (p_repeat == -1) { - p_repeat = 1; - } - - while (p_repeat) { - if (p_cursor.atEnd()) { - break; - } - - int start, end; - // [start, end] is current WORD. - VEditUtils::findCurrentWORD(p_cursor, start, end); - // Move cursor to end of current WORD. - p_cursor.setPosition(end, p_moveMode); - - if (p_repeat == 1 - && checkMode(VimMode::Normal) - && p_moveMode == QTextCursor::KeepAnchor) { - // dW/yW/cW will stop at the end of the line. - moveCursorAcrossSpaces(p_cursor, p_moveMode, true, true); - if (p_cursor.atBlockEnd()) { - --p_repeat; - continue; - } - } - - // Skip spaces. - moveCursorAcrossSpaces(p_cursor, p_moveMode, true); - if (p_cursor.atBlockEnd()) { - continue; - } - - --p_repeat; - } - - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } - - case Movement::ForwardEndOfWord: - { - // Go to the end of current word or next word. - if (p_repeat == -1) { - p_repeat = 1; - } - - int pos = p_cursor.position(); - bool leftSideBefore = useLeftSideOfCursor(p_cursor); - // First move to the end of current word. - p_cursor.movePosition(QTextCursor::EndOfWord, p_moveMode, 1); - if (p_cursor.position() > pos) { - if (p_cursor.position() > pos + 1 || (leftSideBefore && useLeftSideOfCursor(p_cursor))) { - // We did move. - p_repeat -= 1; - } - } - - while (p_repeat) { - if (p_cursor.atEnd()) { - break; - } - - pos = p_cursor.position(); - p_cursor.movePosition(QTextCursor::EndOfWord, p_moveMode); - if (p_cursor.position() == pos) { - // Need to move to the start of next word. - p_cursor.movePosition(QTextCursor::NextWord, p_moveMode); - if (p_cursor.atBlockEnd()) { - continue; - } - - p_cursor.movePosition(QTextCursor::EndOfWord, p_moveMode); - if (p_cursor.atBlockStart()) { - continue; - } - } - - --p_repeat; - } - - // Move one character back. - if (!p_cursor.atBlockStart()) { - if (p_moveMode == QTextCursor::MoveAnchor - || (checkMode(VimMode::Visual) && !useLeftSideOfCursor(p_cursor))) { - p_cursor.movePosition(QTextCursor::PreviousCharacter, p_moveMode); - } - } - - hasMoved = true; - break; - } - - case Movement::ForwardEndOfWORD: - { - // Go to the end of current WORD or next WORD. - if (p_repeat == -1) { - p_repeat = 1; - } - - int pos = p_cursor.position(); - bool leftSideBefore = useLeftSideOfCursor(p_cursor); - while (p_repeat) { - if (p_cursor.atEnd()) { - break; - } - - // Skip spaces. - moveCursorAcrossSpaces(p_cursor, p_moveMode, true); - if (p_cursor.atBlockEnd()) { - continue; - } - - int start, end; - // [start, end] is current WORD. - VEditUtils::findCurrentWORD(p_cursor, start, end); - - // Move cursor to the end of current WORD. - p_cursor.setPosition(end, p_moveMode); - - if (p_cursor.position() > pos + 1 - || (leftSideBefore && useLeftSideOfCursor(p_cursor))) { - --p_repeat; - } - } - - // Move one character back. - if (!p_cursor.atBlockStart()) { - if (p_moveMode == QTextCursor::MoveAnchor - || (checkMode(VimMode::Visual) && !useLeftSideOfCursor(p_cursor))) { - p_cursor.movePosition(QTextCursor::PreviousCharacter, p_moveMode); - } - } - - hasMoved = true; - break; - } - - case Movement::WordBackward: - { - // Go to the start of previous word or current word. - if (p_repeat == -1) { - p_repeat = 1; - } - - int pos = p_cursor.position(); - // first move to the start of current word. - p_cursor.movePosition(QTextCursor::StartOfWord, p_moveMode); - if (p_cursor.position() == pos && useLeftSideOfCursor(p_cursor)) { - // Cursor did not move and now is at the start of a word. - // Actually we are using the left side character so we need to move - // to previous word. - p_cursor.movePosition(QTextCursor::PreviousWord, p_moveMode); - } - - if (p_cursor.position() < pos) { - if (p_cursor.position() < pos - 1 || !useLeftSideOfCursor(p_cursor)) { - // We did move. - p_repeat -= 1; - } - } - - while (p_repeat) { - if (p_cursor.atStart()) { - break; - } - - pos = p_cursor.position(); - p_cursor.movePosition(QTextCursor::StartOfWord, p_moveMode); - if (p_cursor.position() == pos) { - // Need to move to the start of previous word. - p_cursor.movePosition(QTextCursor::PreviousWord, p_moveMode); - if (p_cursor.atBlockEnd()) { - continue; - } - - if (p_cursor.atBlockStart() && doc->characterAt(p_cursor.position()).isSpace()) { - continue; - } - } - - --p_repeat; - } - - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } - - case Movement::WORDBackward: - { - // Go to the start of previous WORD or current WORD. - if (p_repeat == -1) { - p_repeat = 1; - } - - int pos = p_cursor.position(); - while (p_repeat) { - if (p_cursor.atStart()) { - break; - } - - // Skip Spaces. - moveCursorAcrossSpaces(p_cursor, p_moveMode, false); - if (p_cursor.atBlockStart()) { - continue; - } - - p_cursor.movePosition(QTextCursor::PreviousCharacter, p_moveMode); - - int start, end; - // [start, end] is current WORD. - VEditUtils::findCurrentWORD(p_cursor, start, end); - - // Move cursor to the start of current WORD. - p_cursor.setPosition(start, p_moveMode); - - if (p_cursor.position() < pos - 1 || !useLeftSideOfCursor(p_cursor)) { - --p_repeat; - } - } - - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } - - case Movement::BackwardEndOfWord: - { - // Go to the end of previous word. - if (p_repeat == -1) { - p_repeat = 1; - } - - if (useLeftSideOfCursor(p_cursor)) { - // Move one previous char. - p_cursor.movePosition(QTextCursor::PreviousCharacter, p_moveMode); - } - - int pos = p_cursor.position(); - // Move across spaces backward. - moveCursorAcrossSpaces(p_cursor, p_moveMode, false); - int start, end; - VEditUtils::findCurrentWord(p_cursor, start, end); - if (pos != p_cursor.position() || start == end || start == pos) { - // We are alreay at the end of previous word. - --p_repeat; - - // Move it to the start of current word. - p_cursor.movePosition(QTextCursor::PreviousWord, p_moveMode); - } else { - p_cursor.movePosition(QTextCursor::StartOfWord, p_moveMode); - } - - while (p_repeat) { - if (p_cursor.atStart()) { - break; - } - - p_cursor.movePosition(QTextCursor::PreviousWord, p_moveMode); - if (p_cursor.atBlockEnd()) { - continue; - } - - if (p_cursor.atBlockStart() && doc->characterAt(p_cursor.position()).isSpace()) { - continue; - } - - --p_repeat; - } - - // Move it to the end. - p_cursor.movePosition(QTextCursor::EndOfWord, p_moveMode); - - // Move one character back. - if (!p_cursor.atBlockStart()) { - if (p_moveMode == QTextCursor::MoveAnchor - || (checkMode(VimMode::Visual) && !useLeftSideOfCursor(p_cursor)) - || p_cursor.position() <= p_cursor.anchor()) { - p_cursor.movePosition(QTextCursor::PreviousCharacter, p_moveMode); - } - } - - hasMoved = true; - break; - } - - case Movement::BackwardEndOfWORD: - { - // Go to the end of previous WORD. - if (p_repeat == -1) { - p_repeat = 1; - } - - if (useLeftSideOfCursor(p_cursor)) { - // Move one previous char. - p_cursor.movePosition(QTextCursor::PreviousCharacter, p_moveMode); - } - - int pos = p_cursor.position(); - // Move across spaces backward. - moveCursorAcrossSpaces(p_cursor, p_moveMode, false); - int start, end; - VEditUtils::findCurrentWORD(p_cursor, start, end); - if (pos != p_cursor.position() || start == end) { - // We are alreay at the end of previous WORD. - --p_repeat; - - // Move it to the start of current WORD. - p_cursor.setPosition(start, p_moveMode); - } else { - // Move it to the start of current WORD. - p_cursor.setPosition(start, p_moveMode); - } - - while (p_repeat) { - if (p_cursor.atStart()) { - break; - } - - moveCursorAcrossSpaces(p_cursor, p_moveMode, false); - if (p_cursor.atBlockStart()) { - continue; - } - - if (p_cursor.atBlockStart() && doc->characterAt(p_cursor.position()).isSpace()) { - continue; - } - - VEditUtils::findCurrentWORD(p_cursor, start, end); - p_cursor.setPosition(start, p_moveMode); - - --p_repeat; - } - - // Move it to the end. - VEditUtils::findCurrentWORD(p_cursor, start, end); - p_cursor.setPosition(end, p_moveMode); - - // Move one character back. - if (!p_cursor.atBlockStart()) { - if (p_moveMode == QTextCursor::MoveAnchor - || (checkMode(VimMode::Visual) && !useLeftSideOfCursor(p_cursor)) - || p_cursor.position() <= p_cursor.anchor()) { - p_cursor.movePosition(QTextCursor::PreviousCharacter, p_moveMode); - } - } - - hasMoved = true; - break; - } - - case Movement::TillBackward: - forward = false; - // Fall through. - case Movement::TillForward: - inclusive = false; - goto handle_target; - - case Movement::FindBackward: - forward = false; - // Fall through. - case Movement::FindForward: - { -handle_target: - if (p_repeat == -1) { - p_repeat = 1; - } - - const Key &key = p_token.m_key; - QChar target = keyToChar(key.m_key, key.m_modifiers); - if (!target.isNull()) { - hasMoved = VEditUtils::findTargetWithinBlock(p_cursor, - p_moveMode, - target, - forward, - inclusive, - useLeftSideOfCursor(p_cursor), - p_repeat); - } - - break; - } - - case Movement::MarkJump: - // Fall through. - case Movement::MarkJumpLine: - { - // repeat is useless here. - const Key &key = p_token.m_key; - QChar target = keyToChar(key.m_key, key.m_modifiers); - Location loc = m_marks.getMarkLocation(target); - if (loc.isValid()) { - if (loc.m_blockNumber >= doc->blockCount()) { - // Invalid block number. - message(tr("Mark not set")); - m_marks.clearMark(target); - break; - } - - // Different from Vim: - // We just use the block number for mark, so if we delete the line - // where the mark locates, we could not detect if it is set or not. - QTextBlock block = doc->findBlockByNumber(loc.m_blockNumber); - p_cursor.setPosition(block.position(), p_moveMode); - if (p_token.m_movement == Movement::MarkJump) { - setCursorPositionInBlock(p_cursor, loc.m_positionInBlock, p_moveMode); - } else { - // Jump to the first non-space character. - VEditUtils::moveCursorFirstNonSpaceCharacter(p_cursor, p_moveMode); - } - - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - } - - break; - } - - case Movement::FindPair: - { - Q_ASSERT(p_repeat == -1); - int anchor = p_cursor.anchor(); - int position = p_cursor.position(); - QList> pairs; - pairs.append(QPair('(', ')')); - pairs.append(QPair('[', ']')); - pairs.append(QPair('{', '}')); - - // Find forward for a pair (), [], and {}. - QList targets; - for (auto const & pair : pairs) { - targets.append(pair.first); - targets.append(pair.second); - } - - // First check if current char hits the targets. - bool useLeftSideBefore = useLeftSideOfCursor(p_cursor); - QChar ch = doc->characterAt(useLeftSideBefore ? position - 1 - : position); - int idx = targets.indexOf(ch); - if (idx == -1) { - idx = VEditUtils::findTargetsWithinBlock(p_cursor, - targets, - true, - useLeftSideOfCursor(p_cursor), - true); - } else if (useLeftSideBefore) { - // Move one character back to let p_cursor position at the pair. - p_cursor.movePosition(QTextCursor::PreviousCharacter, p_moveMode); - } - - if (idx == -1) { - break; - } - - idx /= 2; - int pairPosition = p_cursor.position(); - bool ret = VEditUtils::selectPairTargetAround(p_cursor, - pairs.at(idx).first, - pairs.at(idx).second, - true, - true, - 1); - - if (ret) { - // Found matched pair. - int first = p_cursor.position(); - int second = p_cursor.anchor(); - if (first > second) { - int tmp = first; - first = second; - second = tmp; - } - - --second; - - int target = first; - if (first == pairPosition) { - target = second; - } - - p_cursor.setPosition(anchor); - p_cursor.setPosition(target, p_moveMode); - - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } else { - // Restore the cursor position. - p_cursor.setPosition(anchor); - if (anchor != position) { - p_cursor.setPosition(position, QTextCursor::KeepAnchor); - } - } - - break; - } - - case Movement::FindPrevious: - forward = false; - // Fall through. - case Movement::FindNext: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - if (m_searchHistory.isEmpty()) { - break; - } - - // Record current location. - m_locations.addLocation(p_cursor); - - bool useLeftSideBefore = useLeftSideOfCursor(p_cursor); - const SearchItem &item = m_searchHistory.lastItem(); - while (--p_repeat >= 0) { - bool found = m_editor->findText(item.m_text, - item.m_options, - forward ? item.m_forward : !item.m_forward, - &p_cursor, - p_moveMode, - useLeftSideBefore); - if (found) { - hasMoved = true; - useLeftSideBefore = false; - } else { - break; - } - } - - if (hasMoved) { - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - } - - break; - } - - case Movement::FindPreviousWordUnderCursor: - forward = false; - // Fall through. - case Movement::FindNextWordUnderCursor: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - // Get current word under cursor. - // Different from Vim: - // We do not recognize a word as strict as Vim. - int start, end; - VEditUtils::findCurrentWord(p_cursor, start, end); - if (start == end) { - // Spaces, find next word. - QTextCursor cursor = p_cursor; - while (true) { - moveCursorAcrossSpaces(cursor, p_moveMode, true); - if (cursor.atEnd()) { - break; - } - - if (!doc->characterAt(cursor.position()).isSpace()) { - VEditUtils::findCurrentWord(cursor, start, end); - Q_ASSERT(start != end); - break; - } - } - - if (start == end) { - break; - } - } - - QTextCursor cursor = p_cursor; - cursor.setPosition(start); - cursor.setPosition(end, QTextCursor::KeepAnchor); - QString text = cursor.selectedText(); - if (text.isEmpty()) { - break; - } - - // Record current location. - m_locations.addLocation(p_cursor); - - p_cursor.setPosition(start, p_moveMode); - - // Case-insensitive, non-regularexpression. - SearchItem item; - item.m_rawStr = text; - item.m_text = text; - item.m_forward = forward; - - m_searchHistory.addItem(item); - m_searchHistory.resetIndex(); - while (--p_repeat >= 0) { - hasMoved = m_editor->findText(item.m_text, item.m_options, - item.m_forward, - &p_cursor, p_moveMode); - } - - Q_ASSERT(hasMoved); - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - break; - } - - case Movement::ParagraphUp: - forward = false; - // Fall through. - case Movement::ParagraphDown: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - // Record current location. - m_locations.addLocation(p_cursor); - - int oriPos = p_cursor.position(); - - int position = VEditUtils::findNextEmptyBlock(p_cursor, - forward, - p_repeat); - if (position == -1) { - // No empty block. Move to the first/last character. - p_cursor.movePosition(forward ? QTextCursor::End : QTextCursor::Start, - p_moveMode); - hasMoved = p_cursor.position() != oriPos; - } else { - p_cursor.setPosition(position, p_moveMode); - hasMoved = true; - } - - break; - } - - default: - break; - } - - return hasMoved; -} - -bool VVim::selectRange(QTextCursor &p_cursor, const QTextDocument *p_doc, - Range p_range, int p_repeat) -{ - bool hasMoved = false; - QTextCursor::MoveMode moveMode = QTextCursor::KeepAnchor; - bool around = false; - QChar opening; - QChar closing; - bool crossBlock = false; - bool multipleTargets = false; - - Q_UNUSED(p_doc); - - switch (p_range) { - case Range::Line: - { - // Visual mode, just select selected lines. - if (checkMode(VimMode::Visual) || checkMode(VimMode::VisualLine)) { - expandSelectionToWholeLines(p_cursor); - hasMoved = true; - break; - } - - // Current line and next (p_repeat - 1) lines. - if (p_repeat == -1) { - p_repeat = 1; - } - - if (p_repeat > 1) { - p_cursor.movePosition(QTextCursor::NextBlock, moveMode, p_repeat - 1); - } - - expandSelectionToWholeLines(p_cursor); - hasMoved = true; - break; - } - - case Range::WordAround: - around = true; - // Fall through. - case Range::WordInner: - { - Q_ASSERT(p_repeat == -1); - bool spaces = false; - int start, end; - VEditUtils::findCurrentWord(p_cursor, start, end); - - if (start == end) { - // Select the space between previous word and next word. - findCurrentSpace(p_cursor, start, end); - spaces = true; - } - - if (start != end) { - p_cursor.setPosition(start, QTextCursor::MoveAnchor); - p_cursor.setPosition(end, moveMode); - hasMoved = true; - - if (around) { - if (spaces) { - // Select the word by the end of spaces. - if (!p_cursor.atBlockEnd()) { - p_cursor.movePosition(QTextCursor::EndOfWord, moveMode); - } - } else { - // Select additional spaces at two ends. - expandSelectionAcrossSpacesWithinBlock(p_cursor); - } - } - } - - break; - } - - case Range::WORDAround: - around = true; - // Fall through. - case Range::WORDInner: - { - Q_ASSERT(p_repeat == -1); - bool spaces = false; - int start, end; - findCurrentSpace(p_cursor, start, end); - - if (start == end) { - VEditUtils::findCurrentWORD(p_cursor, start, end); - } else { - // Select the space between previous WORD and next WORD. - spaces = true; - } - - if (start != end) { - p_cursor.setPosition(start, QTextCursor::MoveAnchor); - p_cursor.setPosition(end, moveMode); - hasMoved = true; - - if (around) { - if (spaces) { - // Select the WORD by the end of spaces. - if (!p_cursor.atBlockEnd()) { - // Skip spaces (mainly across block). - moveCursorAcrossSpaces(p_cursor, moveMode, true); - - // [start, end] is current WORD. - VEditUtils::findCurrentWORD(p_cursor, start, end); - - // Move cursor to the end of current WORD. - p_cursor.setPosition(end, moveMode); - } - } else { - // Select additional spaces at two ends. - expandSelectionAcrossSpacesWithinBlock(p_cursor); - } - } - } - - break; - } - - case Range::ParenthesisAround: - { - around = true; - opening = '('; - closing = ')'; - crossBlock = true; - multipleTargets = true; - goto handlePairTarget; - } - - case Range::ParenthesisInner: - { - around = false; - opening = '('; - closing = ')'; - crossBlock = true; - multipleTargets = true; - goto handlePairTarget; - } - - case Range::BracketAround: - { - around = true; - opening = '['; - closing = ']'; - crossBlock = true; - multipleTargets = true; - goto handlePairTarget; - } - - case Range::BracketInner: - { - around = false; - opening = '['; - closing = ']'; - crossBlock = true; - multipleTargets = true; - goto handlePairTarget; - } - - case Range::AngleBracketAround: - { - around = true; - opening = '<'; - closing = '>'; - crossBlock = true; - multipleTargets = true; - goto handlePairTarget; - } - - case Range::AngleBracketInner: - { - around = false; - opening = '<'; - closing = '>'; - crossBlock = true; - multipleTargets = true; - goto handlePairTarget; - } - - case Range::BraceAround: - { - around = true; - opening = '{'; - closing = '}'; - crossBlock = true; - multipleTargets = true; - goto handlePairTarget; - } - - case Range::BraceInner: - { - around = false; - opening = '{'; - closing = '}'; - crossBlock = true; - multipleTargets = true; - goto handlePairTarget; - } - - case Range::DoubleQuoteAround: - { - around = true; - opening = '"'; - closing = '"'; - crossBlock = false; - multipleTargets = false; - goto handlePairTarget; - } - - case Range::DoubleQuoteInner: - { - around = false; - opening = '"'; - closing = '"'; - crossBlock = false; - multipleTargets = false; - goto handlePairTarget; - } - - case Range::BackQuoteAround: - { - around = true; - opening = '`'; - closing = '`'; - crossBlock = false; - multipleTargets = false; - goto handlePairTarget; - } - - case Range::BackQuoteInner: - { - around = false; - opening = '`'; - closing = '`'; - crossBlock = false; - multipleTargets = false; - goto handlePairTarget; - } - - case Range::QuoteAround: - { - around = true; - opening = '\''; - closing = '\''; - crossBlock = false; - multipleTargets = false; - goto handlePairTarget; - } - - case Range::QuoteInner: - { - around = false; - opening = '\''; - closing = '\''; - crossBlock = false; - multipleTargets = false; - -handlePairTarget: - - if (p_repeat == -1) { - p_repeat = 1; - } else if (p_repeat > 1 && !multipleTargets) { - // According to the behavior of Vim. - p_repeat = 1; - around = true; - } - - hasMoved = VEditUtils::selectPairTargetAround(p_cursor, - opening, - closing, - around, - crossBlock, - p_repeat); - break; - } - - default: - break; - } - - return hasMoved; -} - -void VVim::processDeleteAction(QList &p_tokens) -{ - Token to = p_tokens.takeFirst(); - int repeat = -1; - if (to.isRepeat()) { - repeat = to.m_repeat; - to = p_tokens.takeFirst(); - } - - if ((!to.isMovement() && !to.isRange()) || !p_tokens.isEmpty()) { - p_tokens.clear(); - return; - } - - QTextCursor cursor = m_editor->textCursorW(); - QTextDocument *doc = m_editor->documentW(); - bool hasMoved = false; - QTextCursor::MoveMode moveMode = QTextCursor::KeepAnchor; - - if (to.isRange()) { - cursor.beginEditBlock(); - hasMoved = selectRange(cursor, doc, to.m_range, repeat); - if (hasMoved) { - // Whether the range may cross blocks. - bool mayCrossBlock = false; - - switch (to.m_range) { - case Range::Line: - { - // dd, delete current line. - if (cursor.hasSelection()) { - repeat = VEditUtils::selectedBlockCount(cursor); - deleteSelectedText(cursor, true); - } else { - VEditUtils::removeBlock(cursor); - saveToRegister("\n"); - repeat = 1; - } - - message(tr("%1 fewer %2").arg(repeat).arg(repeat > 1 ? tr("lines") - : tr("line"))); - break; - } - - case Range::ParenthesisInner: - // Fall through. - case Range::ParenthesisAround: - // Fall through. - case Range::BracketInner: - // Fall through. - case Range::BracketAround: - // Fall through. - case Range::AngleBracketInner: - // Fall through. - case Range::AngleBracketAround: - // Fall through. - case Range::BraceInner: - // Fall through. - case Range::BraceAround: - // Fall through. - mayCrossBlock = true; - - V_FALLTHROUGH; - - case Range::WordAround: - // Fall through. - case Range::WordInner: - // Fall through. - case Range::WORDAround: - // Fall through. - case Range::WORDInner: - // Fall through. - case Range::QuoteInner: - // Fall through. - case Range::QuoteAround: - // Fall through. - case Range::DoubleQuoteInner: - // Fall through. - case Range::DoubleQuoteAround: - // Fall through. - case Range::BackQuoteInner: - // Fall through. - case Range::BackQuoteAround: - { - if (cursor.hasSelection()) { - bool clearEmptyBlock = false; - if (mayCrossBlock - && VEditUtils::selectedBlockCount(cursor) > 1) { - clearEmptyBlock = true; - } - - int blockCount = 0; - if (clearEmptyBlock) { - blockCount = doc->blockCount(); - } - - deleteSelectedText(cursor, clearEmptyBlock); - - if (clearEmptyBlock) { - int nrBlock = blockCount - doc->blockCount(); - Q_ASSERT(nrBlock > 0); - message(tr("%1 fewer %2").arg(nrBlock).arg(nrBlock > 1 ? tr("lines") - : tr("line"))); - } - } - - break; - } - - default: - return; - } - } - - cursor.endEditBlock(); - goto exit; - } - - V_ASSERT(to.isMovement()); - - // Filter out not supported movement for DELETE action. - switch (to.m_movement) { - case Movement::PageUp: - case Movement::PageDown: - case Movement::HalfPageUp: - case Movement::HalfPageDown: - return; - - default: - break; - } - - cursor.beginEditBlock(); - if (checkMode(VimMode::VisualLine) || checkMode(VimMode::Visual)) { - // Visual mode, omitting repeat and movement. - // Different from Vim: - // If there is no selection in Visual mode, we do nothing. - if (cursor.hasSelection()) { - hasMoved = true; - deleteSelectedText(cursor, m_mode == VimMode::VisualLine); - } else if (checkMode(VimMode::Visual)) { - hasMoved = true; - VEditUtils::removeBlock(cursor); - saveToRegister("\n"); - } - - cursor.endEditBlock(); - goto exit; - } - - hasMoved = processMovement(cursor, moveMode, to, repeat); - if (repeat == -1) { - repeat = 1; - } - - if (hasMoved) { - bool clearEmptyBlock = false; - switch (to.m_movement) { - case Movement::Up: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "delete up" << repeat << "lines"; - break; - } - - case Movement::Down: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "delete down" << repeat << "lines"; - break; - } - - case Movement::EndOfLine: - { - // End of line (block). - if (repeat > 1) { - clearEmptyBlock = true; - } - - qDebug() << "delete till end of" << repeat << "line"; - break; - } - - case Movement::LineJump: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "delete till line" << repeat; - break; - } - - case Movement::StartOfDocument: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "delete till start of document"; - break; - } - - case Movement::EndOfDocument: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "delete till end of document"; - break; - } - - // ParagraphUp and ParagraphDown are a little different from Vim in - // block deletion. - - default: - break; - } - - if (clearEmptyBlock) { - int nrBlock = VEditUtils::selectedBlockCount(cursor); - message(tr("%1 fewer %2").arg(nrBlock).arg(nrBlock > 1 ? tr("lines") - : tr("line"))); - } - - deleteSelectedText(cursor, clearEmptyBlock); - } - - cursor.endEditBlock(); - -exit: - if (hasMoved) { - m_editor->setTextCursorW(cursor); - } -} - -void VVim::processCopyAction(QList &p_tokens) -{ - Token to = p_tokens.takeFirst(); - int repeat = -1; - if (to.isRepeat()) { - repeat = to.m_repeat; - to = p_tokens.takeFirst(); - } - - if ((!to.isMovement() && !to.isRange()) || !p_tokens.isEmpty()) { - p_tokens.clear(); - return; - } - - QTextCursor cursor = m_editor->textCursorW(); - QTextDocument *doc = m_editor->documentW(); - int oriPos = cursor.position(); - bool changed = false; - QTextCursor::MoveMode moveMode = QTextCursor::KeepAnchor; - - if (to.isRange()) { - cursor.beginEditBlock(); - changed = selectRange(cursor, doc, to.m_range, repeat); - if (changed) { - // Whether the range may cross blocks. - bool mayCrossBlock = false; - - switch (to.m_range) { - case Range::Line: - { - // yy, copy current line. - if (cursor.hasSelection()) { - repeat = VEditUtils::selectedBlockCount(cursor); - copySelectedText(cursor, true); - } else { - saveToRegister("\n"); - repeat = 1; - } - - message(tr("%1 %2 yanked").arg(repeat).arg(repeat > 1 ? tr("lines") - : tr("line"))); - break; - } - - case Range::ParenthesisInner: - // Fall through. - case Range::ParenthesisAround: - // Fall through. - case Range::BracketInner: - // Fall through. - case Range::BracketAround: - // Fall through. - case Range::AngleBracketInner: - // Fall through. - case Range::AngleBracketAround: - // Fall through. - case Range::BraceInner: - // Fall through. - case Range::BraceAround: - // Fall through. - mayCrossBlock = true; - - V_FALLTHROUGH; - - case Range::WordAround: - // Fall through. - case Range::WordInner: - // Fall through. - case Range::WORDAround: - // Fall through. - case Range::WORDInner: - // Fall through. - case Range::QuoteInner: - // Fall through. - case Range::QuoteAround: - // Fall through. - case Range::DoubleQuoteInner: - // Fall through. - case Range::DoubleQuoteAround: - // Fall through. - case Range::BackQuoteInner: - // Fall through. - case Range::BackQuoteAround: - { - if (cursor.hasSelection()) { - bool multipleBlocks = false; - int nrBlock = VEditUtils::selectedBlockCount(cursor); - if (mayCrossBlock && nrBlock > 1) { - multipleBlocks = true; - } - - // No need to add new line even crossing multiple blocks. - copySelectedText(cursor, false); - - if (multipleBlocks) { - message(tr("%1 %2 yanked").arg(nrBlock).arg(nrBlock > 1 ? tr("lines") - : tr("line"))); - } - } - - break; - } - - default: - return; - } - } - - if (cursor.position() != oriPos) { - cursor.setPosition(oriPos); - changed = true; - } - - cursor.endEditBlock(); - goto exit; - } - - V_ASSERT(to.isMovement()); - - // Filter out not supported movement for Copy action. - switch (to.m_movement) { - case Movement::PageUp: - case Movement::PageDown: - case Movement::HalfPageUp: - case Movement::HalfPageDown: - return; - - default: - break; - } - - cursor.beginEditBlock(); - changed = processMovement(cursor, moveMode, to, repeat); - if (repeat == -1) { - repeat = 1; - } - - if (changed) { - bool addNewLine = false; - switch (to.m_movement) { - case Movement::Up: - { - expandSelectionToWholeLines(cursor); - addNewLine = true; - qDebug() << "copy up" << repeat << "lines"; - break; - } - - case Movement::Down: - { - expandSelectionToWholeLines(cursor); - addNewLine = true; - qDebug() << "copy down" << repeat << "lines"; - break; - } - - case Movement::EndOfLine: - { - // End of line (block). - // Do not need to add new line even if repeat > 1. - qDebug() << "copy till end of" << repeat << "line"; - break; - } - - case Movement::LineJump: - { - expandSelectionToWholeLines(cursor); - addNewLine = true; - qDebug() << "copy till line" << repeat; - break; - } - - case Movement::StartOfDocument: - { - expandSelectionToWholeLines(cursor); - addNewLine = true; - qDebug() << "copy till start of document"; - break; - } - - case Movement::EndOfDocument: - { - expandSelectionToWholeLines(cursor); - addNewLine = true; - qDebug() << "copy till end of document"; - break; - } - - default: - break; - } - - if (addNewLine) { - int nrBlock = VEditUtils::selectedBlockCount(cursor); - message(tr("%1 %2 yanked").arg(nrBlock).arg(nrBlock > 1 ? tr("lines") - : tr("line"))); - } - - copySelectedText(cursor, addNewLine); - if (cursor.position() != oriPos) { - cursor.setPosition(oriPos); - } - } - - cursor.endEditBlock(); - -exit: - if (changed) { - m_editor->setTextCursorW(cursor); - } -} - -void VVim::processPasteAction(QList &p_tokens, bool p_pasteBefore) -{ - int repeat = 1; - if (!p_tokens.isEmpty()) { - Token to = p_tokens.takeFirst(); - if (!p_tokens.isEmpty() || !to.isRepeat()) { - p_tokens.clear(); - return; - } - - repeat = to.m_repeat; - } - - Register ® = getRegister(m_regName); - QString value = reg.read(); - bool isBlock = reg.isBlock(); - if (value.isEmpty()) { - if (checkMode(VimMode::Visual) || checkMode(VimMode::VisualLine)) { - setMode(VimMode::Normal); - } - - return; - } - - if (!(checkMode(VimMode::Normal) - || checkMode(VimMode::Visual) - || checkMode(VimMode::VisualLine))) { - return; - } - - QString text; - text.reserve(repeat * value.size() + 1); - for (int i = 0; i < repeat; ++i) { - text.append(value); - } - - bool changed = false; - int nrBlock = 0; - int restorePos = -1; - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - - // Different from Vim: - // In visual mode, by default vim select the current char, so paste operation will replace - // current char, but here it is strange to follow this specification. - bool isVisualLine = checkMode(VimMode::VisualLine); - if (!checkMode(VimMode::Normal)) { - // Visual or VisualLine mode. - if (cursor.hasSelection()) { - int pos = cursor.selectionStart(); - deleteSelectedText(cursor, isVisualLine); - if (isVisualLine) { - // Insert a new block for insertion. - insertChangeBlockAfterDeletion(cursor, pos); - - restorePos = cursor.position(); - - if (isBlock) { - nrBlock = text.count('\n'); - // insertChangeBlockAfterDeletion() already insert a new line, so eliminate one here. - text = text.left(text.size() - 1); - } - } else if (isBlock) { - // Insert new block right at current cursor. - nrBlock = text.count('\n'); - cursor.insertBlock(); - restorePos = cursor.position(); - } else if (text.count('\n') > 0) { - restorePos = cursor.position(); - } - - changed = true; - } - } else { - // Normal mode. - if (isBlock) { - if (p_pasteBefore) { - cursor.movePosition(QTextCursor::StartOfBlock); - cursor.insertBlock(); - cursor.movePosition(QTextCursor::PreviousBlock); - } else { - cursor.movePosition(QTextCursor::EndOfBlock); - cursor.insertBlock(); - } - - restorePos = cursor.position(); - - nrBlock = text.count('\n'); - - // inserBlock() already insert a new line, so eliminate one here. - text = text.left(text.size() - 1); - } else { - // Not a block. - if (!p_pasteBefore && !cursor.atBlockEnd()) { - // Insert behind current cursor. - cursor.movePosition(QTextCursor::Right); - } - - if (text.count('\n') > 0) { - restorePos = cursor.position(); - } - } - - changed = true; - } - - if (changed) { - cursor.insertText(text); - - if (restorePos == -1) { - // Move cursor one character left. - cursor.movePosition(QTextCursor::Left); - } else { - // Move cursor at the right position. - cursor.setPosition(restorePos); - } - - if (nrBlock > 0) { - message(tr("%1 more %2").arg(nrBlock).arg(nrBlock > 1 ? tr("lines") - : tr("line"))); - } - } - - cursor.endEditBlock(); - - if (!checkMode(VimMode::Normal)) { - setMode(VimMode::Normal); - } - - if (changed) { - m_editor->setTextCursorW(cursor); - } - - qDebug() << "text pasted" << text; -} - -void VVim::processChangeAction(QList &p_tokens) -{ - Token to = p_tokens.takeFirst(); - int repeat = -1; - if (to.isRepeat()) { - repeat = to.m_repeat; - to = p_tokens.takeFirst(); - } - - if ((!to.isMovement() && !to.isRange()) || !p_tokens.isEmpty()) { - p_tokens.clear(); - return; - } - - QTextCursor cursor = m_editor->textCursorW(); - QTextDocument *doc = m_editor->documentW(); - bool hasMoved = false; - QTextCursor::MoveMode moveMode = QTextCursor::KeepAnchor; - - if (to.isRange()) { - cursor.beginEditBlock(); - hasMoved = selectRange(cursor, doc, to.m_range, repeat); - if (hasMoved) { - int pos = cursor.selectionStart(); - - switch (to.m_range) { - case Range::Line: - { - // cc, change current line. - if (cursor.hasSelection()) { - deleteSelectedText(cursor, true); - insertChangeBlockAfterDeletion(cursor, pos); - } else { - saveToRegister("\n"); - } - - break; - } - - case Range::ParenthesisInner: - // Fall through. - case Range::ParenthesisAround: - // Fall through. - case Range::BracketInner: - // Fall through. - case Range::BracketAround: - // Fall through. - case Range::AngleBracketInner: - // Fall through. - case Range::AngleBracketAround: - // Fall through. - case Range::BraceInner: - // Fall through. - case Range::BraceAround: - // Fall through. - case Range::WordAround: - // Fall through. - case Range::WordInner: - // Fall through. - case Range::WORDAround: - // Fall through. - case Range::WORDInner: - // Fall through. - case Range::QuoteInner: - // Fall through. - case Range::QuoteAround: - // Fall through. - case Range::DoubleQuoteInner: - // Fall through. - case Range::DoubleQuoteAround: - // Fall through. - case Range::BackQuoteInner: - // Fall through. - case Range::BackQuoteAround: - { - if (cursor.hasSelection()) { - deleteSelectedText(cursor, false); - } - - break; - } - - default: - return; - } - } - - cursor.endEditBlock(); - goto exit; - } - - V_ASSERT(to.isMovement()); - - // Filter out not supported movement for Change action. - switch (to.m_movement) { - case Movement::PageUp: - case Movement::PageDown: - case Movement::HalfPageUp: - case Movement::HalfPageDown: - return; - - default: - break; - } - - cursor.beginEditBlock(); - if (checkMode(VimMode::VisualLine) || checkMode(VimMode::Visual)) { - // Visual mode, omitting repeat and movement. - // Different from Vim: - // If there is no selection in Visual mode, we do nothing. - bool visualLine = checkMode(VimMode::VisualLine); - if (cursor.hasSelection()) { - hasMoved = true; - int pos = cursor.selectionStart(); - deleteSelectedText(cursor, visualLine); - if (visualLine) { - insertChangeBlockAfterDeletion(cursor, pos); - } - } else if (visualLine) { - hasMoved = true; - saveToRegister("\n"); - } - - cursor.endEditBlock(); - goto exit; - } - - hasMoved = processMovement(cursor, moveMode, to, repeat); - if (repeat == -1) { - repeat = 1; - } - - if (hasMoved) { - bool clearEmptyBlock = false; - switch (to.m_movement) { - case Movement::Left: - { - qDebug() << "change backward" << repeat << "chars"; - break; - } - - case Movement::Right: - { - qDebug() << "change forward" << repeat << "chars"; - break; - } - - case Movement::Up: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "change up" << repeat << "lines"; - break; - } - - case Movement::Down: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "change down" << repeat << "lines"; - break; - } - - case Movement::VisualUp: - { - qDebug() << "change visual up" << repeat << "lines"; - break; - } - - case Movement::VisualDown: - { - qDebug() << "change visual down" << repeat << "lines"; - break; - } - - case Movement::StartOfLine: - { - qDebug() << "change till start of line"; - break; - } - - case Movement::EndOfLine: - { - // End of line (block). - if (repeat > 1) { - clearEmptyBlock = true; - } - - qDebug() << "change till end of" << repeat << "line"; - break; - } - - case Movement::FirstCharacter: - { - qDebug() << "change till first non-space character"; - break; - } - - case Movement::LineJump: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "change till line" << repeat; - break; - } - - case Movement::StartOfDocument: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "change till start of document"; - break; - } - - case Movement::EndOfDocument: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "change till end of document"; - break; - } - - case Movement::WordForward: - { - qDebug() << "change" << repeat << "words forward"; - break; - } - - case Movement::WORDForward: - { - qDebug() << "change" << repeat << "WORDs forward"; - break; - } - - case Movement::ForwardEndOfWord: - { - qDebug() << "change" << repeat << "end of words forward"; - break; - } - - case Movement::ForwardEndOfWORD: - { - qDebug() << "change" << repeat << "end of WORDs forward"; - break; - } - - case Movement::WordBackward: - { - qDebug() << "change" << repeat << "words backward"; - break; - } - - case Movement::WORDBackward: - { - qDebug() << "change" << repeat << "WORDs backward"; - break; - } - - case Movement::BackwardEndOfWord: - { - qDebug() << "change" << repeat << "end of words backward"; - break; - } - - case Movement::BackwardEndOfWORD: - { - qDebug() << "change" << repeat << "end of WORDs backward"; - break; - } - - default: - break; - } - - if (cursor.hasSelection()) { - int pos = cursor.selectionStart(); - bool allDeleted = false; - if (pos == 0) { - QTextBlock block = m_editor->documentW()->lastBlock(); - if (block.position() + block.length() - 1 == cursor.selectionEnd()) { - allDeleted = true; - } - } - - deleteSelectedText(cursor, clearEmptyBlock); - if (clearEmptyBlock && !allDeleted) { - insertChangeBlockAfterDeletion(cursor, pos); - } - } - } - - cursor.endEditBlock(); - -exit: - if (hasMoved) { - m_editor->setTextCursorW(cursor); - } - - setMode(VimMode::Insert); -} - -void VVim::processIndentAction(QList &p_tokens, IndentType p_type) -{ - Token to = p_tokens.takeFirst(); - int repeat = -1; - if (to.isRepeat()) { - repeat = to.m_repeat; - to = p_tokens.takeFirst(); - } - - if ((!to.isMovement() && !to.isRange()) || !p_tokens.isEmpty()) { - p_tokens.clear(); - return; - } - - QTextCursor cursor = m_editor->textCursorW(); - - QString op; - switch (p_type) { - case IndentType::Indent: - op = ">"; - break; - - case IndentType::UnIndent: - op = "<"; - break; - - case IndentType::AutoIndent: - op = "="; - break; - - default: - Q_ASSERT(false); - } - - if (to.isRange()) { - bool changed = selectRange(cursor, m_editor->documentW(), to.m_range, repeat); - if (changed) { - switch (to.m_range) { - case Range::Line: - { - // >>/<<, indent/unindent current line. - if (repeat == -1) { - repeat = 1; - } - - if (p_type == IndentType::AutoIndent) { - VEditUtils::indentSelectedBlocksAsBlock(cursor, false); - } else { - VEditUtils::indentSelectedBlocks(cursor, - m_editConfig->m_tabSpaces, - p_type == IndentType::Indent); - } - - message(tr("%1 %2 %3ed 1 time").arg(repeat) - .arg(repeat > 1 ? tr("lines") - : tr("line")) - .arg(op)); - break; - } - - case Range::ParenthesisInner: - // Fall through. - case Range::ParenthesisAround: - // Fall through. - case Range::BracketInner: - // Fall through. - case Range::BracketAround: - // Fall through. - case Range::AngleBracketInner: - // Fall through. - case Range::AngleBracketAround: - // Fall through. - case Range::BraceInner: - // Fall through. - case Range::BraceAround: - // Fall through. - case Range::WordAround: - // Fall through. - case Range::WordInner: - // Fall through. - case Range::WORDAround: - // Fall through. - case Range::WORDInner: - // Fall through. - case Range::QuoteInner: - // Fall through. - case Range::QuoteAround: - // Fall through. - case Range::DoubleQuoteInner: - // Fall through. - case Range::DoubleQuoteAround: - // Fall through. - case Range::BackQuoteInner: - // Fall through. - case Range::BackQuoteAround: - { - int nrBlock = VEditUtils::selectedBlockCount(cursor); - if (p_type == IndentType::AutoIndent) { - VEditUtils::indentSelectedBlocksAsBlock(cursor, false); - } else { - VEditUtils::indentSelectedBlocks(cursor, - m_editConfig->m_tabSpaces, - p_type == IndentType::Indent); - } - - message(tr("%1 %2 %3ed 1 time").arg(nrBlock) - .arg(nrBlock > 1 ? tr("lines") - : tr("line")) - .arg(op)); - break; - } - - default: - return; - } - } - - return; - } - - V_ASSERT(to.isMovement()); - - // Filter out not supported movement for Indent/UnIndent action. - switch (to.m_movement) { - case Movement::PageUp: - case Movement::PageDown: - case Movement::HalfPageUp: - case Movement::HalfPageDown: - return; - - default: - break; - } - - if (checkMode(VimMode::VisualLine) || checkMode(VimMode::Visual)) { - // Visual mode, omitting repeat and movement. - // Different from Vim: - // Do not exit Visual mode after indentation/unindentation. - if (p_type == IndentType::AutoIndent) { - VEditUtils::indentSelectedBlocksAsBlock(cursor, false); - } else { - VEditUtils::indentSelectedBlocks(cursor, - m_editConfig->m_tabSpaces, - p_type == IndentType::Indent); - } - - return; - } - - processMovement(cursor, - QTextCursor::KeepAnchor, - to, - repeat); - - int nrBlock = VEditUtils::selectedBlockCount(cursor); - if (p_type == IndentType::AutoIndent) { - VEditUtils::indentSelectedBlocksAsBlock(cursor, false); - } else { - VEditUtils::indentSelectedBlocks(cursor, - m_editConfig->m_tabSpaces, - p_type == IndentType::Indent); - } - - message(tr("%1 %2 %3ed 1 time").arg(nrBlock) - .arg(nrBlock > 1 ? tr("lines") - : tr("line")) - .arg(op)); -} - -void VVim::processToLowerAction(QList &p_tokens, bool p_toLower) -{ - Token to = p_tokens.takeFirst(); - int repeat = -1; - if (to.isRepeat()) { - repeat = to.m_repeat; - to = p_tokens.takeFirst(); - } - - if ((!to.isMovement() && !to.isRange()) || !p_tokens.isEmpty()) { - p_tokens.clear(); - return; - } - - QTextCursor cursor = m_editor->textCursorW(); - QTextDocument *doc = m_editor->documentW(); - bool changed = false; - QTextCursor::MoveMode moveMode = QTextCursor::KeepAnchor; - int oriPos = cursor.position(); - - if (to.isRange()) { - cursor.beginEditBlock(); - changed = selectRange(cursor, doc, to.m_range, repeat); - if (changed) { - oriPos = cursor.selectionStart(); - int nrBlock = VEditUtils::selectedBlockCount(cursor); - message(tr("%1 %2 changed").arg(nrBlock) - .arg(nrBlock > 1 ? tr("lines") : tr("line"))); - - convertCaseOfSelectedText(cursor, p_toLower); - - cursor.setPosition(oriPos); - } - - cursor.endEditBlock(); - goto exit; - } - - V_ASSERT(to.isMovement()); - - // Filter out not supported movement for ToLower/ToUpper action. - switch (to.m_movement) { - case Movement::PageUp: - case Movement::PageDown: - case Movement::HalfPageUp: - case Movement::HalfPageDown: - return; - - default: - break; - } - - cursor.beginEditBlock(); - changed = processMovement(cursor, - moveMode, - to, - repeat); - if (repeat == -1) { - repeat = 1; - } - - if (changed) { - oriPos = cursor.selectionStart(); - - switch (to.m_movement) { - case Movement::Up: - { - expandSelectionToWholeLines(cursor); - break; - } - - case Movement::Down: - { - expandSelectionToWholeLines(cursor); - break; - } - - case Movement::LineJump: - { - expandSelectionToWholeLines(cursor); - break; - } - - case Movement::StartOfDocument: - { - expandSelectionToWholeLines(cursor); - break; - } - - case Movement::EndOfDocument: - { - expandSelectionToWholeLines(cursor); - break; - } - - default: - break; - } - - int nrBlock = VEditUtils::selectedBlockCount(cursor); - message(tr("%1 %2 changed").arg(nrBlock).arg(nrBlock > 1 ? tr("lines") - : tr("line"))); - - convertCaseOfSelectedText(cursor, p_toLower); - - cursor.setPosition(oriPos); - } - - cursor.endEditBlock(); - -exit: - if (changed) { - m_editor->setTextCursorW(cursor); - } -} - -void VVim::processUndoAction(QList &p_tokens) -{ - int repeat = 1; - if (!p_tokens.isEmpty()) { - Token to = p_tokens.takeFirst(); - if (!p_tokens.isEmpty() || !to.isRepeat()) { - p_tokens.clear(); - return; - } - - repeat = to.m_repeat; - } - - QTextDocument *doc = m_editor->documentW(); - int i = 0; - for (i = 0; i < repeat && doc->isUndoAvailable(); ++i) { - m_editor->undoW(); - } - - message(tr("Undo %1 %2").arg(i).arg(i > 1 ? tr("changes") : tr("change"))); -} - -void VVim::processRedoAction(QList &p_tokens) -{ - int repeat = 1; - if (!p_tokens.isEmpty()) { - Token to = p_tokens.takeFirst(); - if (!p_tokens.isEmpty() || !to.isRepeat()) { - p_tokens.clear(); - return; - } - - repeat = to.m_repeat; - } - - QTextDocument *doc = m_editor->documentW(); - int i = 0; - for (i = 0; i < repeat && doc->isRedoAvailable(); ++i) { - m_editor->redoW(); - } - - message(tr("Redo %1 %2").arg(i).arg(i > 1 ? tr("changes") : tr("change"))); -} - -void VVim::processRedrawLineAction(QList &p_tokens, int p_dest) -{ - QTextCursor cursor = m_editor->textCursorW(); - int repeat = cursor.block().blockNumber(); - if (!p_tokens.isEmpty()) { - Token to = p_tokens.takeFirst(); - if (!p_tokens.isEmpty() || !to.isRepeat()) { - p_tokens.clear(); - return; - } - - repeat = to.m_repeat - 1; - } - - m_editor->scrollBlockInPage(repeat, p_dest); -} - -void VVim::processJumpLocationAction(QList &p_tokens, bool p_next) -{ - int repeat = 1; - if (!p_tokens.isEmpty()) { - Token to = p_tokens.takeFirst(); - if (!p_tokens.isEmpty() || !to.isRepeat()) { - p_tokens.clear(); - return; - } - - repeat = to.m_repeat; - } - - QTextCursor cursor = m_editor->textCursorW(); - Location loc; - if (p_next) { - while (m_locations.hasNext() && repeat > 0) { - --repeat; - loc = m_locations.nextLocation(); - } - } else { - while (m_locations.hasPrevious() && repeat > 0) { - --repeat; - loc = m_locations.previousLocation(cursor); - } - } - - if (loc.isValid()) { - QTextDocument *doc = m_editor->documentW(); - if (loc.m_blockNumber >= doc->blockCount()) { - message(tr("Mark has invalid line number")); - return; - } - - QTextBlock block = doc->findBlockByNumber(loc.m_blockNumber); - int pib = loc.m_positionInBlock; - if (pib >= block.length()) { - pib = block.length() - 1; - } - - if (!m_editor->isBlockVisible(block)) { - // Scroll the block to the center of screen. - m_editor->scrollBlockInPage(block.blockNumber(), 1); - } - - cursor.setPosition(block.position() + pib); - m_editor->setTextCursorW(cursor); - } -} - -void VVim::processReplaceAction(QList &p_tokens) -{ - int repeat = 1; - QChar replaceChar; - Q_ASSERT(!p_tokens.isEmpty()); - Token to = p_tokens.takeFirst(); - if (to.isRepeat()) { - repeat = to.m_repeat; - Q_ASSERT(!p_tokens.isEmpty()); - to = p_tokens.takeFirst(); - } - - Q_ASSERT(to.isKey() && p_tokens.isEmpty()); - replaceChar = keyToChar(to.m_key.m_key, to.m_key.m_modifiers); - if (replaceChar.isNull()) { - return; - } - - if (!(checkMode(VimMode::Normal) - || checkMode(VimMode::Visual) - || checkMode(VimMode::VisualLine))) { - return; - } - - // Replace the next repeat characters with replaceChar until the end of line. - // If repeat is greater than the number of left characters in current line, - // do nothing. - // In visual mode, repeat is ignored. - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - if (checkMode(VimMode::Normal)) { - // Select the characters to be replaced. - cursor.clearSelection(); - int pib = cursor.positionInBlock(); - int nrChar = cursor.block().length() - 1 - pib; - if (repeat <= nrChar) { - cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, repeat); - } - } - - bool changed = replaceSelectedTextWithCharacter(cursor, replaceChar); - cursor.endEditBlock(); - - if (changed) { - m_editor->setTextCursorW(cursor); - setMode(VimMode::Normal); - } -} - -void VVim::processReverseCaseAction(QList &p_tokens) -{ - int repeat = 1; - if (!p_tokens.isEmpty()) { - Token to = p_tokens.takeFirst(); - Q_ASSERT(to.isRepeat() && p_tokens.isEmpty()); - repeat = to.m_repeat; - } - - if (!(checkMode(VimMode::Normal) - || checkMode(VimMode::Visual) - || checkMode(VimMode::VisualLine))) { - return; - } - - // Reverse the next repeat characters' case until the end of line. - // If repeat is greater than the number of left characters in current line, - // just change the actual number of left characters. - // In visual mode, repeat is ignored and reverse the selected text. - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - if (checkMode(VimMode::Normal)) { - // Select the characters to be replaced. - cursor.clearSelection(); - int pib = cursor.positionInBlock(); - int nrChar = cursor.block().length() - 1 - pib; - cursor.movePosition(QTextCursor::Right, - QTextCursor::KeepAnchor, - repeat > nrChar ? nrChar : repeat); - } - - bool changed = reverseSelectedTextCase(cursor); - cursor.endEditBlock(); - - if (changed) { - m_editor->setTextCursorW(cursor); - setMode(VimMode::Normal); - } -} - -void VVim::processJoinAction(QList &p_tokens, bool p_modifySpaces) -{ - int repeat = 2; - if (!p_tokens.isEmpty()) { - Token to = p_tokens.takeFirst(); - Q_ASSERT(to.isRepeat() && p_tokens.isEmpty()); - repeat = qMax(to.m_repeat, repeat); - } - - if (!(checkMode(VimMode::Normal) - || checkMode(VimMode::Visual) - || checkMode(VimMode::VisualLine))) { - return; - } - - // Join repeat lines, with the minimum of two lines. Do nothing when on the - // last line. - // If @p_modifySpaces is true, remove the indent and insert up to two spaces. - // If repeat is too big, it is reduced to the number of lines available. - // In visual mode, repeat is ignored and join the highlighted lines. - int firstBlock = -1; - int blockCount = repeat; - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - if (checkMode(VimMode::Normal)) { - firstBlock = cursor.block().blockNumber(); - } else { - QTextDocument *doc = m_editor->documentW(); - firstBlock = doc->findBlock(cursor.selectionStart()).blockNumber(); - int lastBlock = doc->findBlock(cursor.selectionEnd()).blockNumber(); - blockCount = lastBlock - firstBlock + 1; - } - - bool changed = joinLines(cursor, firstBlock, blockCount, p_modifySpaces); - cursor.endEditBlock(); - - if (changed) { - m_editor->setTextCursorW(cursor); - setMode(VimMode::Normal); - } -} - -bool VVim::clearSelection() -{ - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.hasSelection()) { - cursor.clearSelection(); - m_editor->setTextCursorW(cursor); - return true; - } - - return false; -} - -int VVim::blockCountOfPageStep() const -{ - int lineCount = m_editor->documentW()->blockCount(); - QScrollBar *bar = m_editor->verticalScrollBarW(); - int steps = (bar->maximum() - bar->minimum() + bar->pageStep()); - int pageLineCount = lineCount * (bar->pageStep() * 1.0 / steps); - return pageLineCount; -} - -void VVim::maintainSelectionInVisualMode(QTextCursor *p_cursor) -{ - // We need to always select the character on current position. - QTextCursor *cursor = p_cursor; - QTextCursor tmpCursor = m_editor->textCursorW(); - if (!cursor) { - cursor = &tmpCursor; - } - - bool hasChanged = false; - int pos = cursor->position(); - int anchor = cursor->anchor(); - - if (pos > anchor) { - Q_ASSERT(pos > m_positionBeforeVisualMode); - if (anchor > m_positionBeforeVisualMode) { - // Re-select. - cursor->setPosition(m_positionBeforeVisualMode); - cursor->setPosition(pos, QTextCursor::KeepAnchor); - hasChanged = true; - } - - setCursorBlockMode(m_editor, CursorBlock::LeftSide); - } else if (pos == anchor) { - Q_ASSERT(anchor >= m_positionBeforeVisualMode); - // Re-select. - if (anchor == m_positionBeforeVisualMode) { - cursor->setPosition(m_positionBeforeVisualMode + 1); - cursor->setPosition(pos, QTextCursor::KeepAnchor); - hasChanged = true; - - setCursorBlockMode(m_editor, CursorBlock::RightSide); - } else { - cursor->setPosition(m_positionBeforeVisualMode); - cursor->setPosition(pos, QTextCursor::KeepAnchor); - hasChanged = true; - - setCursorBlockMode(m_editor, CursorBlock::LeftSide); - } - } else { - // Re-select. - if (anchor <= m_positionBeforeVisualMode) { - cursor->setPosition(m_positionBeforeVisualMode + 1); - cursor->setPosition(pos, QTextCursor::KeepAnchor); - hasChanged = true; - } - - setCursorBlockMode(m_editor, CursorBlock::RightSide); - } - - if (hasChanged && !p_cursor) { - m_editor->setTextCursorW(*cursor); - } -} - -void VVim::expandSelectionToWholeLines(QTextCursor &p_cursor) -{ - QTextDocument *doc = m_editor->documentW(); - int curPos = p_cursor.position(); - int anchorPos = p_cursor.anchor(); - QTextBlock curBlock = doc->findBlock(curPos); - QTextBlock anchorBlock = doc->findBlock(anchorPos); - - if (curPos >= anchorPos) { - p_cursor.setPosition(anchorBlock.position(), QTextCursor::MoveAnchor); - p_cursor.setPosition(curBlock.position() + curBlock.length() - 1, - QTextCursor::KeepAnchor); - } else { - p_cursor.setPosition(anchorBlock.position() + anchorBlock.length() - 1, - QTextCursor::MoveAnchor); - p_cursor.setPosition(curBlock.position(), - QTextCursor::KeepAnchor); - } -} - -void VVim::initRegisters() -{ - if (!s_registers.isEmpty()) { - return; - } - - for (char ch = 'a'; ch <= 'z'; ++ch) { - s_registers[QChar(ch)] = Register(QChar(ch)); - } - - s_registers[c_unnamedRegister] = Register(c_unnamedRegister); - s_registers[c_blackHoleRegister] = Register(c_blackHoleRegister); - s_registers[c_selectionRegister] = Register(c_selectionRegister); -} - -bool VVim::expectingRegisterName() const -{ - return m_keys.size() == 1 - && m_keys.at(0) == Key(Qt::Key_QuoteDbl, Qt::ShiftModifier); -} - -bool VVim::expectingCharacterTarget() const -{ - if (m_keys.size() != 1) { - return false; - } - - const Key &key = m_keys.first(); - return (key == Key(Qt::Key_F, Qt::NoModifier) - || key == Key(Qt::Key_F, Qt::ShiftModifier) - || key == Key(Qt::Key_T, Qt::NoModifier) - || key == Key(Qt::Key_T, Qt::ShiftModifier)); -} - -bool VVim::expectingReplaceCharacter() const -{ - return m_keys.size() == 1 - && m_keys.first() == Key(Qt::Key_R, Qt::NoModifier); -} - -bool VVim::expectingLeaderSequence() const -{ - if (m_replayLeaderSequence || m_keys.isEmpty()) { - return false; - } - - return m_keys.first() == Key(Qt::Key_Backslash); -} - -bool VVim::expectingMarkName() const -{ - return checkPendingKey(Key(Qt::Key_M)) && m_tokens.isEmpty(); -} - -bool VVim::expectingMarkTarget() const -{ - return checkPendingKey(Key(Qt::Key_Apostrophe)) - || checkPendingKey(Key(Qt::Key_QuoteLeft)); -} - -QChar VVim::keyToRegisterName(const Key &p_key) const -{ - if (p_key.isAlphabet()) { - return p_key.toAlphabet().toLower(); - } - - switch (p_key.m_key) { - case Qt::Key_QuoteDbl: - if (p_key.m_modifiers == Qt::ShiftModifier) { - return c_unnamedRegister; - } - - break; - - case Qt::Key_Plus: - if (p_key.m_modifiers == Qt::ShiftModifier) { - return c_selectionRegister; - } - - break; - - case Qt::Key_Underscore: - if (p_key.m_modifiers == Qt::ShiftModifier) { - return c_blackHoleRegister; - } - - break; - - default: - break; - } - - return QChar(); -} - -bool VVim::hasActionToken() const -{ - // There will be only one action token and it is placed at the front. - bool has = false; - if (m_tokens.isEmpty()) { - return false; - } - - if (m_tokens.at(0).isAction()) { - has = true; - } - - for (int i = 1; i < m_tokens.size(); ++i) { - V_ASSERT(!m_tokens.at(i).isAction()); - } - - return has; -} - -bool VVim::hasRepeatToken() const -{ - // There will be only one repeat token. - bool has = false; - if (m_tokens.isEmpty()) { - return false; - } - - for (int i = 0; i < m_tokens.size(); ++i) { - if (m_tokens.at(i).isRepeat()) { - V_ASSERT(!has); - has = true; - } - } - - return has; -} - -bool VVim::hasActionTokenValidForTextObject() const -{ - if (hasActionToken()) { - Action act = m_tokens.first().m_action; - if (act == Action::Delete - || act == Action::Copy - || act == Action::Change - || act == Action::ToLower - || act == Action::ToUpper - || act == Action::Indent - || act == Action::UnIndent) { - return true; - } - } - - return false; -} - -bool VVim::checkActionToken(Action p_action) const -{ - if (hasActionToken()) { - return m_tokens.first().m_action == p_action; - } - - return false; -} - -bool VVim::checkPendingKey(const Key &p_key) const -{ - return (m_keys.size() == 1 && m_keys.first() == p_key); -} - -void VVim::tryAddMoveAction() -{ - if (!hasActionToken()) { - addActionToken(Action::Move); - } -} - -void VVim::addActionToken(Action p_action) -{ - V_ASSERT(!hasActionToken()); - m_tokens.prepend(Token(p_action)); -} - -const VVim::Token *VVim::getActionToken() const -{ - V_ASSERT(hasActionToken()); - return &m_tokens.first(); -} - -VVim::Token *VVim::getRepeatToken() -{ - V_ASSERT(hasRepeatToken()); - - for (auto & token : m_tokens) { - if (token.isRepeat()) { - return &token; - } - } - - return NULL; -} - -void VVim::addRangeToken(Range p_range) -{ - m_tokens.append(Token(p_range)); -} - -void VVim::addMovementToken(Movement p_movement) -{ - m_tokens.append(Token(p_movement)); -} - -void VVim::addMovementToken(Movement p_movement, Key p_key) -{ - m_tokens.append(Token(p_movement, p_key)); -} - -void VVim::addKeyToken(Key p_key) -{ - m_tokens.append(Token(p_key)); -} - -void VVim::deleteSelectedText(QTextCursor &p_cursor, bool p_clearEmptyBlock) -{ - if (p_cursor.hasSelection()) { - QString deletedText = VEditUtils::selectedText(p_cursor); - p_cursor.removeSelectedText(); - if (p_clearEmptyBlock && p_cursor.block().length() == 1) { - deletedText += "\n"; - VEditUtils::removeBlock(p_cursor); - } - - saveToRegister(deletedText); - } -} - -void VVim::copySelectedText(bool p_addNewLine) -{ - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.hasSelection()) { - cursor.beginEditBlock(); - copySelectedText(cursor, p_addNewLine); - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); - } -} - -void VVim::copySelectedText(QTextCursor &p_cursor, bool p_addNewLine) -{ - if (p_cursor.hasSelection()) { - QString text = VEditUtils::selectedText(p_cursor); - p_cursor.clearSelection(); - if (p_addNewLine) { - text += "\n"; - } - - saveToRegister(text); - } -} - -void VVim::convertCaseOfSelectedText(QTextCursor &p_cursor, bool p_toLower) -{ - if (p_cursor.hasSelection()) { - QTextDocument *doc = p_cursor.document(); - int start = p_cursor.selectionStart(); - int end = p_cursor.selectionEnd(); - p_cursor.clearSelection(); - p_cursor.setPosition(start); - int pos = p_cursor.position(); - while (pos < end) { - QChar ch = doc->characterAt(pos); - bool modified = false; - if (p_toLower) { - if (ch.isUpper()) { - ch = ch.toLower(); - modified = true; - } - } else if (ch.isLower()) { - ch = ch.toUpper(); - modified = true; - } - - if (modified) { - p_cursor.deleteChar(); - p_cursor.insertText(ch); - } else { - p_cursor.movePosition(QTextCursor::NextCharacter); - } - - pos = p_cursor.position(); - } - } -} - -void VVim::saveToRegister(const QString &p_text) -{ - QString text(p_text); - VEditUtils::removeObjectReplacementCharacter(text); - - qDebug() << QString("save text(%1) to register(%2)").arg(text).arg(m_regName); - - Register ® = getRegister(m_regName); - reg.update(text); - - if (!reg.isBlackHoleRegister() && !reg.isUnnamedRegister()) { - // Save it to unnamed register. - setRegister(c_unnamedRegister, reg.m_value); - } -} - -void VVim::Register::update(const QString &p_value) -{ - QChar newLine('\n'); - bool newIsBlock = false; - if (p_value.endsWith(newLine)) { - newIsBlock = true; - } - - bool oriIsBlock = isBlock(); - if (isNamedRegister() && m_append) { - // Append @p_value to m_value. - if (newIsBlock) { - if (oriIsBlock) { - m_value += p_value; - } else { - m_value.append(newLine); - m_value += p_value; - } - } else if (oriIsBlock) { - m_value += p_value; - m_value.append(newLine); - } else { - m_value += p_value; - } - } else { - // Set m_value to @p_value. - m_value = p_value; - } - - if (isSelectionRegister()) { - // Change system clipboard. - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(m_value); - } -} - -const QString &VVim::Register::read() -{ - if (isSelectionRegister()) { - // Update from system clipboard. - QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - if (mimeData->hasText()) { - m_value = mimeData->text(); - } else { - m_value.clear(); - } - } - - return m_value; -} - -void VVim::repeatLastFindMovement(bool p_reverse) -{ - if (!m_lastFindToken.isValid()) { - return; - } - - V_ASSERT(m_lastFindToken.isMovement()); - - Movement mm = m_lastFindToken.m_movement; - Key key = m_lastFindToken.m_key; - - V_ASSERT(key.isValid()); - - if (p_reverse) { - switch (mm) { - case Movement::FindForward: - mm = Movement::FindBackward; - break; - - case Movement::FindBackward: - mm = Movement::FindForward; - break; - - case Movement::TillForward: - mm = Movement::TillBackward; - break; - - case Movement::TillBackward: - mm = Movement::TillForward; - break; - - default: - break; - } - } - - tryAddMoveAction(); - addMovementToken(mm, key); - processCommand(m_tokens); -} - -void VVim::message(const QString &p_msg) -{ - if (!p_msg.isEmpty()) { - qDebug() << "vim msg:" << p_msg; - emit vimMessage(p_msg); - } -} - -const QMap &VVim::getRegisters() const -{ - return s_registers; -} - -const VVim::Marks &VVim::getMarks() const -{ - return m_marks; -} - -QChar VVim::getCurrentRegisterName() const -{ - return m_regName; -} - -QString VVim::getPendingKeys() const -{ - QString str; - for (auto const & key : m_pendingKeys) { - str.append(keyToString(key.m_key, key.m_modifiers)); - } - - return str; -} - -void VVim::setCurrentRegisterName(QChar p_reg) -{ - m_regName = p_reg; -} - -bool VVim::checkMode(VimMode p_mode) -{ - return m_mode == p_mode; -} - -bool VVim::processCommandLine(VVim::CommandLineType p_type, const QString &p_cmd) -{ - setMode(VimMode::Normal); - - bool ret = false; - switch (p_type) { - case CommandLineType::Command: - ret = executeCommand(p_cmd); - break; - - case CommandLineType::SearchForward: - // Fall through. - case CommandLineType::SearchBackward: - { - SearchItem item = fetchSearchItem(p_type, p_cmd); - m_editor->findText(item.m_text, item.m_options, item.m_forward); - m_searchHistory.addItem(item); - m_searchHistory.resetIndex(); - break; - } - - default: - break; - } - - return ret; -} - -void VVim::processCommandLineChanged(VVim::CommandLineType p_type, - const QString &p_cmd) -{ - setMode(VimMode::Normal); - - if (p_type == CommandLineType::SearchForward - || p_type == CommandLineType::SearchBackward) { - // Peek text. - SearchItem item = fetchSearchItem(p_type, p_cmd); - m_editor->peekText(item.m_text, item.m_options, item.m_forward); - } -} - -void VVim::processCommandLineCancelled() -{ - m_searchHistory.resetIndex(); - m_editor->clearIncrementalSearchedWordHighlight(); -} - -VVim::SearchItem VVim::fetchSearchItem(VVim::CommandLineType p_type, - const QString &p_cmd) -{ - Q_ASSERT(p_type == CommandLineType::SearchForward - || p_type == CommandLineType::SearchBackward); - - SearchItem item; - item.m_rawStr = p_cmd; - item.m_text = p_cmd; - item.m_forward = p_type == CommandLineType::SearchForward; - - if (p_cmd.indexOf("\\C") > -1) { - item.m_options |= FindOption::CaseSensitive; - item.m_text.remove("\\C"); - } - - item.m_options |= FindOption::RegularExpression; - - return item; -} - -bool VVim::executeCommand(const QString &p_cmd) -{ - bool validCommand = true; - QString msg; - - Q_ASSERT(m_tokens.isEmpty() && m_keys.isEmpty()); - if (p_cmd.isEmpty()) { - return true; - }else if (p_cmd.size() == 1) { - if (p_cmd == "w") { - // :w, save current file. - emit m_editor->object()->saveNote(); - msg = tr("Note has been saved"); - } else if (p_cmd == "q") { - // :q, quit edit mode. - emit m_editor->object()->discardAndRead(); - msg = tr("Quit"); - } else if (p_cmd == "x") { - // :x, save if there is any change and quit edit mode. - emit m_editor->object()->saveAndRead(); - msg = tr("Quit with note having been saved"); - } else { - validCommand = false; - } - } else if (p_cmd.size() == 2) { - if (p_cmd == "wq") { - // :wq, save change and quit edit mode. - // We treat it same as :x. - emit m_editor->object()->saveAndRead(); - msg = tr("Quit with note having been saved"); - } else if (p_cmd == "q!") { - // :q!, discard change and quit edit mode. - emit m_editor->object()->discardAndRead(); - msg = tr("Quit"); - } else { - validCommand = false; - } - } else if (p_cmd == "nohlsearch") { - // :nohlsearch, clear highlight search. - clearSearchHighlight(); - } else { - validCommand = false; - } - - if (!validCommand) { - bool allDigits = true; - for (int i = 0; i < p_cmd.size(); ++i) { - if (!p_cmd[i].isDigit()) { - allDigits = false; - break; - } - } - - // All digits. - // Jump to a specific line. - if (allDigits) { - bool ok; - int num = p_cmd.toInt(&ok, 10); - if (num == 0) { - num = 1; - } - - if (ok && num > 0) { - m_tokens.append(Token(num)); - tryAddMoveAction(); - addMovementToken(Movement::LineJump); - processCommand(m_tokens); - validCommand = true; - } - } - } - - if (!validCommand) { - message(tr("Not an editor command: %1").arg(p_cmd)); - } else { - message(msg); - } - - return validCommand; -} - -bool VVim::hasNonDigitPendingKeys(const QList &p_keys) -{ - for (auto const &key : p_keys) { - if (!key.isDigit()) { - return true; - } - } - - return false; -} - -bool VVim::hasNonDigitPendingKeys() -{ - return hasNonDigitPendingKeys(m_keys); -} - -bool VVim::processLeaderSequence(const Key &p_key) -{ - // Different from Vim: - // If it is not a valid sequence, we just do nothing here. - V_ASSERT(checkPendingKey(Key(Qt::Key_Backslash))); - bool validSequence = true; - QList replaySeq; - - if (p_key == Key(Qt::Key_Y)) { - // y, "+y - replaySeq.append(Key(Qt::Key_QuoteDbl, Qt::ShiftModifier)); - replaySeq.append(Key(Qt::Key_Plus, Qt::ShiftModifier)); - replaySeq.append(Key(Qt::Key_Y)); - } else if (p_key == Key(Qt::Key_D)) { - // d, "+d - replaySeq.append(Key(Qt::Key_QuoteDbl, Qt::ShiftModifier)); - replaySeq.append(Key(Qt::Key_Plus, Qt::ShiftModifier)); - replaySeq.append(Key(Qt::Key_D)); - } else if (p_key == Key(Qt::Key_P)) { - // p, "+p - replaySeq.append(Key(Qt::Key_QuoteDbl, Qt::ShiftModifier)); - replaySeq.append(Key(Qt::Key_Plus, Qt::ShiftModifier)); - replaySeq.append(Key(Qt::Key_P)); - } else if (p_key == Key(Qt::Key_P, Qt::ShiftModifier)) { - // P, "+P - replaySeq.append(Key(Qt::Key_QuoteDbl, Qt::ShiftModifier)); - replaySeq.append(Key(Qt::Key_Plus, Qt::ShiftModifier)); - replaySeq.append(Key(Qt::Key_P, Qt::ShiftModifier)); - } else if (p_key == Key(Qt::Key_Space)) { - // , clear search highlight - clearSearchHighlight(); - } else if (p_key == Key(Qt::Key_W)) { - // w, save note - emit m_editor->object()->saveNote(); - message(tr("Note has been saved")); - } else { - validSequence = false; - } - - if (!replaySeq.isEmpty()) { - // Replay the sequence. - m_replayLeaderSequence = true; - m_keys.clear(); - for (int i = 0; i < 2; ++i) { - m_pendingKeys.pop_back(); - } - - for (auto const &key : replaySeq) { - bool ret = handleKeyPressEvent(key.m_key, key.m_modifiers); - if (!ret) { - break; - } - } - - m_replayLeaderSequence = false; - } else { - resetState(); - } - - return validSequence; -} - -VVim::LocationStack::LocationStack(int p_maximum) - : m_pointer(0), c_maximumLocations(p_maximum < 10 ? 10 : p_maximum) -{ -} - -bool VVim::LocationStack::hasPrevious() const -{ - return m_pointer > 0; -} - -bool VVim::LocationStack::hasNext() const -{ - return m_pointer < m_locations.size() - 1; -} - -void VVim::LocationStack::addLocation(const QTextCursor &p_cursor) -{ - int blockNumber = p_cursor.block().blockNumber(); - int pib = p_cursor.positionInBlock(); - - // Remove older location with the same block number. - for (auto it = m_locations.begin(); it != m_locations.end();) { - if (it->m_blockNumber == blockNumber) { - it = m_locations.erase(it); - break; - } else { - ++it; - } - } - - if (m_locations.size() >= c_maximumLocations) { - m_locations.removeFirst(); - } - - m_locations.append(Location(blockNumber, pib)); - - m_pointer = m_locations.size(); - - qDebug() << QString("add location (%1,%2), pointer=%3") - .arg(blockNumber).arg(pib).arg(m_pointer); -} - -const VVim::Location &VVim::LocationStack::previousLocation(const QTextCursor &p_cursor) -{ - V_ASSERT(hasPrevious()); - if (m_pointer == m_locations.size()) { - // Add current location to the stack. - addLocation(p_cursor); - - m_pointer = m_locations.size() - 1; - } - - // Jump to previous location. - if (m_pointer > 0) { - --m_pointer; - } - - qDebug() << QString("previous location (%1,%2), pointer=%3, size=%4") - .arg(m_locations.at(m_pointer).m_blockNumber) - .arg(m_locations.at(m_pointer).m_positionInBlock) - .arg(m_pointer).arg(m_locations.size()); - - return m_locations.at(m_pointer); -} - -const VVim::Location &VVim::LocationStack::nextLocation() -{ - V_ASSERT(hasNext()); - ++m_pointer; - - qDebug() << QString("next location (%1,%2), pointer=%3, size=%4") - .arg(m_locations.at(m_pointer).m_blockNumber) - .arg(m_locations.at(m_pointer).m_positionInBlock) - .arg(m_pointer).arg(m_locations.size()); - - return m_locations.at(m_pointer); -} - -VVim::Marks::Marks() -{ - for (char ch = 'a'; ch <= 'z'; ++ch) { - m_marks[QChar(ch)] = Mark(); - } -} - -void VVim::Marks::setMark(QChar p_name, const QTextCursor &p_cursor) -{ - auto it = m_marks.find(p_name); - if (it == m_marks.end()) { - return; - } - - it->m_location.m_blockNumber = p_cursor.block().blockNumber(); - it->m_location.m_positionInBlock = p_cursor.positionInBlock(); - it->m_text = p_cursor.block().text().trimmed(); - it->m_name = p_name; - - m_lastUsedMark = p_name; - - qDebug() << QString("set mark %1 to (%2,%3)") - .arg(p_name) - .arg(it->m_location.m_blockNumber) - .arg(it->m_location.m_positionInBlock); -} - -void VVim::Marks::clearMark(QChar p_name) -{ - auto it = m_marks.find(p_name); - if (it == m_marks.end()) { - return; - } - - it->m_location = Location(); - it->m_text.clear(); - - if (m_lastUsedMark == p_name) { - m_lastUsedMark = QChar(); - } -} - -VVim::Location VVim::Marks::getMarkLocation(QChar p_name) -{ - auto it = m_marks.find(p_name); - if (it == m_marks.end()) { - return Location(); - } - - if (it->m_location.isValid()) { - m_lastUsedMark = p_name; - } - - return it->m_location; -} - -const QMap &VVim::Marks::getMarks() const -{ - return m_marks; -} - -QChar VVim::Marks::getLastUsedMark() const -{ - return m_lastUsedMark; -} - -void VVim::processTitleJump(const QList &p_tokens, bool p_forward, int p_relativeLevel) -{ - int repeat = 1; - if (p_tokens.size() == 1) { - Token to = p_tokens.first(); - if (to.isRepeat()) { - repeat = to.m_repeat; - } else { - return; - } - } else if (!p_tokens.isEmpty()) { - return; - } - - QTextCursor cursor = m_editor->textCursorW(); - if (m_editor->jumpTitle(p_forward, p_relativeLevel, repeat)) { - // Record current location. - m_locations.addLocation(cursor); - } -} - -void VVim::SearchHistory::addItem(const SearchItem &p_item) -{ - m_isLastItemForward = p_item.m_forward; - if (m_isLastItemForward) { - m_forwardItems.push_back(p_item); - m_forwardIdx = m_forwardItems.size(); - } else { - m_backwardItems.push_back(p_item); - m_backwardIdx = m_forwardItems.size(); - } - - qDebug() << "search history add item" << m_isLastItemForward - << m_forwardIdx << m_forwardItems.size() - << m_backwardIdx << m_backwardItems.size(); -} - -const VVim::SearchItem &VVim::SearchHistory::lastItem() const -{ - if (m_isLastItemForward) { - Q_ASSERT(!m_forwardItems.isEmpty()); - return m_forwardItems.back(); - } else { - Q_ASSERT(!m_backwardItems.isEmpty()); - return m_backwardItems.back(); - } -} - -const VVim::SearchItem &VVim::SearchHistory::nextItem(bool p_forward) -{ - Q_ASSERT(hasNext(p_forward)); - return p_forward ? m_forwardItems.at(++m_forwardIdx) - : m_backwardItems.at(++m_backwardIdx); -} - -// Return previous item in the @p_forward stack. -const VVim::SearchItem &VVim::SearchHistory::previousItem(bool p_forward) -{ - Q_ASSERT(hasPrevious(p_forward)); - qDebug() << "previousItem" << p_forward << m_forwardItems.size() << m_backwardItems.size() - << m_forwardIdx << m_backwardIdx; - return p_forward ? m_forwardItems.at(--m_forwardIdx) - : m_backwardItems.at(--m_backwardIdx); -} - -void VVim::SearchHistory::resetIndex() -{ - m_forwardIdx = m_forwardItems.size(); - m_backwardIdx = m_backwardItems.size(); -} - -QString VVim::getNextCommandHistory(VVim::CommandLineType p_type, - const QString &p_cmd) -{ - Q_UNUSED(p_cmd); - bool forward = false; - QString cmd; - switch (p_type) { - case CommandLineType::SearchForward: - forward = true; - // Fall through. - case CommandLineType::SearchBackward: - if (m_searchHistory.hasNext(forward)) { - return m_searchHistory.nextItem(forward).m_rawStr; - } else { - m_searchHistory.resetIndex(); - } - - break; - - default: - break; - } - - return cmd; -} - -// Get the previous command in history of @p_type. @p_cmd is the current input. -QString VVim::getPreviousCommandHistory(VVim::CommandLineType p_type, - const QString &p_cmd) -{ - Q_UNUSED(p_cmd); - bool forward = false; - QString cmd; - switch (p_type) { - case CommandLineType::SearchForward: - forward = true; - // Fall through. - case CommandLineType::SearchBackward: - if (m_searchHistory.hasPrevious(forward)) { - return m_searchHistory.previousItem(forward).m_rawStr; - } - - break; - - default: - break; - } - - return cmd; -} - -void VVim::clearSearchHighlight() -{ - m_editor->clearSearchedWordHighlight(); -} - -QString VVim::readRegister(int p_key, int p_modifiers) -{ - Key keyInfo(p_key, p_modifiers); - QChar reg = keyToRegisterName(keyInfo); - if (!reg.isNull()) { - return getRegister(reg).read(); - } - - return ""; -} - -void VVim::amendCursorPosition() -{ - if (checkMode(VimMode::Normal)) { - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.atBlockEnd() && !cursor.atBlockStart()) { - // Normal mode and cursor at the end of a non-empty block. - cursor.movePosition(QTextCursor::PreviousCharacter); - m_editor->setTextCursorW(cursor); - } - } -} - -void VVim::handleMousePressed(QMouseEvent *p_event) -{ - Q_UNUSED(p_event); - QTextCursor cursor = m_editor->textCursorW(); - if ((checkMode(VimMode::Visual) || checkMode(VimMode::VisualLine)) - && p_event->buttons() != Qt::RightButton) { - setMode(VimMode::Normal); - } else if (checkMode(VimMode::Normal)) { - if (cursor.hasSelection()) { - setMode(VimMode::Visual, false); - maintainSelectionInVisualMode(); - } - } -} - -void VVim::handleMouseMoved(QMouseEvent *p_event) -{ - if (p_event->buttons() != Qt::LeftButton) { - return; - } - - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.hasSelection()) { - if (checkMode(VimMode::Normal)) { - int pos = cursor.position(); - int anchor = cursor.anchor(); - QTextBlock block = cursor.document()->findBlock(anchor); - if (anchor > 0 && anchor == block.position() + block.length() - 1) { - // Move anchor left. - cursor.setPosition(anchor - 1); - cursor.setPosition(pos, QTextCursor::KeepAnchor); - m_editor->setTextCursorW(cursor); - } - - setMode(VimMode::Visual, false); - maintainSelectionInVisualMode(); - } else if (checkMode(VimMode::Visual)) { - // We need to assure we always select the character on m_positionBeforeVisualMode. - maintainSelectionInVisualMode(); - } - } else if (checkMode(VimMode::Visual)) { - // User move cursor in Visual mode. Now the cursor and anchor - // are at the same position. - maintainSelectionInVisualMode(); - } -} - -void VVim::handleMouseReleased(QMouseEvent *p_event) -{ - Q_UNUSED(p_event); - - if (checkMode(VimMode::Normal)) { - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.hasSelection()) { - return; - } - - amendCursorPosition(); - } -} - -void VVim::setCursorBlockMode(VEditor *p_cursor, CursorBlock p_mode) -{ - p_cursor->setCursorBlockModeW(p_mode); -} - -bool VVim::useLeftSideOfCursor(const QTextCursor &p_cursor) -{ - if (!checkMode(VimMode::Visual)) { - return false; - } - - Q_ASSERT(m_positionBeforeVisualMode >= 0); - return p_cursor.position() > m_positionBeforeVisualMode; -} diff --git a/src/utils/vvim.h b/src/utils/vvim.h deleted file mode 100644 index 8979d0ce..00000000 --- a/src/utils/vvim.h +++ /dev/null @@ -1,892 +0,0 @@ -#ifndef VVIM_H -#define VVIM_H - -#include -#include -#include -#include -#include -#include "vutils.h" - -class VEditor; -class QKeyEvent; -class VEditConfig; -class QKeyEvent; -class QMouseEvent; - -enum class VimMode { - Normal = 0, - Insert, - Visual, - VisualLine, - Replace, - Invalid -}; - -class VVim : public QObject -{ - Q_OBJECT -public: - explicit VVim(VEditor *p_editor); - - // Struct for a location. - struct Location - { - Location() : m_blockNumber(-1), m_positionInBlock(0) - { - } - - Location(int p_blockNumber, int p_positionInBlock) - : m_blockNumber(p_blockNumber), m_positionInBlock(p_positionInBlock) - { - } - - bool isValid() const - { - return m_blockNumber > -1; - } - - // Block number of the location, based on 0. - int m_blockNumber; - - // Position in block, based on 0. - int m_positionInBlock; - }; - - struct Register - { - Register(QChar p_name, const QString &p_value) - : m_name(p_name), m_value(p_value), m_append(false) - { - } - - Register(QChar p_name) - : m_name(p_name), m_append(false) - { - } - - Register() - : m_append(false) - { - } - - // Register a-z. - bool isNamedRegister() const - { - char ch = m_name.toLatin1(); - return ch >= 'a' && ch <= 'z'; - } - - bool isUnnamedRegister() const - { - return m_name == c_unnamedRegister; - } - - bool isBlackHoleRegister() const - { - return m_name == c_blackHoleRegister; - } - - bool isSelectionRegister() const - { - return m_name == c_selectionRegister; - } - - bool isBlock() const - { - return m_value.endsWith('\n'); - } - - // @p_value is the content to update. - // If @p_value ends with \n, then it is a block. - // When @p_value is a block, we need to add \n at the end if necessary. - // If @m_append is true and @p_value is a block, we need to add \n between - // them if necessary. - void update(const QString &p_value); - - // Read the value of this register. - const QString &read(); - - QChar m_name; - QString m_value; - - // This is not info of Register itself, but a hint to the handling logics - // whether we need to append the content to this register. - // Only valid for a-z registers. - bool m_append; - }; - - struct Mark - { - QChar m_name; - Location m_location; - QString m_text; - }; - - // We only support simple local marks a-z. - class Marks - { - public: - Marks(); - - // Set mark @p_name to point to @p_cursor. - void setMark(QChar p_name, const QTextCursor &p_cursor); - - void clearMark(QChar p_name); - - // Return the location of mark @p_name. - Location getMarkLocation(QChar p_name); - - const QMap &getMarks() const; - - QChar getLastUsedMark() const; - - private: - QMap m_marks; - - QChar m_lastUsedMark; - }; - - enum class CommandLineType - { - Command, - SearchForward, - SearchBackward, - Invalid - }; - - // Handle key press event. - // @p_autoIndentPos: the cursor position of last auto indent. - // Returns true if the event is consumed and need no more handling. - bool handleKeyPressEvent(QKeyEvent *p_event, int *p_autoIndentPos = NULL); - - // Return current mode. - VimMode getMode() const; - - // Set current mode. - void setMode(VimMode p_mode, bool p_clearSelection = true, int p_position = -1); - - // Set current register. - void setCurrentRegisterName(QChar p_reg); - - // Get m_registers. - const QMap &getRegisters() const; - - QChar getCurrentRegisterName() const; - - // Get pending keys. - // Turn m_pendingKeys to a string. - QString getPendingKeys() const; - - // Get m_marks. - const VVim::Marks &getMarks() const; - - // Process command line of type @p_type and command @p_cmd. - // Returns true if it is a valid command. - bool processCommandLine(VVim::CommandLineType p_type, const QString &p_cmd); - - // Process the command line text change. - void processCommandLineChanged(VVim::CommandLineType p_type, - const QString &p_cmd); - - void processCommandLineCancelled(); - - // Get the next command in history of @p_type. @p_cmd is the current input. - // Return NULL QString if history is not applicable. - QString getNextCommandHistory(VVim::CommandLineType p_type, - const QString &p_cmd); - - // Get the previous command in history of @p_type. @p_cmd is the current input. - // Return NULL QString if history is not applicable. - QString getPreviousCommandHistory(VVim::CommandLineType p_type, - const QString &p_cmd); - - // Read the register content. - // Returns empty string if it is not a valid register. - QString readRegister(int p_key, int p_modifiers); - -signals: - // Emit when current mode has been changed. - void modeChanged(VimMode p_mode); - - // Emit when VVim want to display some messages. - void vimMessage(const QString &p_msg); - - // Emit when current status updated. - void vimStatusUpdated(const VVim *p_vim); - - // Emit when user pressed : to trigger command line. - void commandLineTriggered(VVim::CommandLineType p_type); - -private slots: - void handleMousePressed(QMouseEvent *p_event); - - void handleMouseMoved(QMouseEvent *p_event); - - void handleMouseReleased(QMouseEvent *p_event); - - // When we display cursor as block, it makes no sense to put cursor at the - // end of line. - void amendCursorPosition(); - -private: - // Struct for a key press. - struct Key - { - Key(int p_key, int p_modifiers = Qt::NoModifier) - : m_key(p_key), m_modifiers(p_modifiers) - { - } - - Key() : m_key(-1), m_modifiers(Qt::NoModifier) {} - - int m_key; - int m_modifiers; - - bool isDigit() const - { - return m_key >= Qt::Key_0 - && m_key <= Qt::Key_9 - && (m_modifiers == Qt::NoModifier || m_modifiers == Qt::KeypadModifier); - } - - int toDigit() const - { - V_ASSERT(isDigit()); - return m_key - Qt::Key_0; - } - - bool isAlphabet() const - { - return m_key >= Qt::Key_A - && m_key <= Qt::Key_Z - && (m_modifiers == Qt::NoModifier || m_modifiers == Qt::ShiftModifier); - } - - QChar toAlphabet() const - { - V_ASSERT(isAlphabet()); - if (m_modifiers == Qt::NoModifier) { - return QChar('a' + (m_key - Qt::Key_A)); - } else { - return QChar('A' + (m_key - Qt::Key_A)); - } - } - - bool isValid() const - { - return m_key > -1 && m_modifiers > -1; - } - - bool operator==(const Key &p_key) const - { - return p_key.m_key == m_key && p_key.m_modifiers == m_modifiers; - } - }; - - // Search item including the searched text and options. - struct SearchItem - { - SearchItem() : m_options(0), m_forward(true) {} - - // The user raw input. - QString m_rawStr; - - // The string used to search. - QString m_text; - - uint m_options; - bool m_forward; - }; - - class SearchHistory - { - public: - SearchHistory() - : m_forwardIdx(0), m_backwardIdx(0), m_isLastItemForward(true) {} - - // Add @p_item to history. - void addItem(const SearchItem &p_item); - - // Whether the history is empty. - bool isEmpty() const - { - return m_forwardItems.isEmpty() && m_backwardItems.isEmpty(); - } - - bool hasNext(bool p_forward) const - { - return p_forward ? m_forwardIdx < m_forwardItems.size() - 1 - : m_backwardIdx < m_backwardItems.size() - 1; - } - - bool hasPrevious(bool p_forward) const - { - return p_forward ? m_forwardIdx > 0 - : m_backwardIdx > 0; - } - - // Return the last search item according to m_isLastItemForward. - // Make sure the history is not empty before calling this. - const SearchItem &lastItem() const; - - // Return next item in the @p_forward stack. - // Make sure before by calling hasNext(). - const SearchItem &nextItem(bool p_forward); - - // Return previous item in the @p_forward stack. - // Make sure before by calling hasPrevious(). - const SearchItem &previousItem(bool p_forward); - - void resetIndex(); - - private: - // Maintain two stacks for the search history. Use the back as the top - // of the stack. - // The idx points to the next item to push. - // Just simply add new search item to the stack, without duplication. - QList m_forwardItems; - int m_forwardIdx; - - QList m_backwardItems; - int m_backwardIdx; - - // Whether last search item is forward or not. - bool m_isLastItemForward; - - static const int c_capacity; - }; - - // Supported actions. - enum class Action - { - Move = 0, - Delete, - Copy, - Paste, - PasteBefore, - Change, - Indent, - UnIndent, - AutoIndent, - ToUpper, - ToLower, - ReverseCase, - Undo, - Redo, - RedrawAtTop, - RedrawAtCenter, - RedrawAtBottom, - JumpPreviousLocation, - JumpNextLocation, - Replace, - Join, - JoinNoModification, - Invalid - }; - - // Supported movements. - enum class Movement - { - Left = 0, - Right, - Up, - Down, - VisualUp, - VisualDown, - PageUp, - PageDown, - HalfPageUp, - HalfPageDown, - StartOfVisualLine, - StartOfLine, - EndOfLine, - FirstCharacter, - LineJump, - StartOfDocument, - EndOfDocument, - WordForward, - WORDForward, - ForwardEndOfWord, - ForwardEndOfWORD, - WordBackward, - WORDBackward, - BackwardEndOfWord, - BackwardEndOfWORD, - FindForward, - FindBackward, - TillForward, - TillBackward, - MarkJump, - MarkJumpLine, - FindPair, - FindNext, - FindPrevious, - FindNextWordUnderCursor, - FindPreviousWordUnderCursor, - ParagraphUp, - ParagraphDown, - Invalid - }; - - // Supported ranges. - enum class Range - { - Line = 0, - WordInner, - WordAround, - WORDInner, - WORDAround, - QuoteInner, - QuoteAround, - DoubleQuoteInner, - DoubleQuoteAround, - BackQuoteInner, - BackQuoteAround, - ParenthesisInner, - ParenthesisAround, - BracketInner, - BracketAround, - AngleBracketInner, - AngleBracketAround, - BraceInner, - BraceAround, - Invalid - }; - - enum class TokenType { Action = 0, Repeat, Movement, Range, Key, Invalid }; - - struct Token - { - Token(Action p_action) - : m_type(TokenType::Action), m_action(p_action) {} - - Token(int p_repeat) - : m_type(TokenType::Repeat), m_repeat(p_repeat) {} - - Token(Movement p_movement) - : m_type(TokenType::Movement), m_movement(p_movement) {} - - Token(Movement p_movement, Key p_key) - : m_type(TokenType::Movement), m_movement(p_movement), m_key(p_key) {} - - Token(Range p_range) - : m_type(TokenType::Range), m_range(p_range) {} - - Token(Key p_key) - : m_type(TokenType::Key), m_key(p_key) {} - - Token() : m_type(TokenType::Invalid) {} - - bool isRepeat() const - { - return m_type == TokenType::Repeat; - } - - bool isAction() const - { - return m_type == TokenType::Action; - } - - bool isMovement() const - { - return m_type == TokenType::Movement; - } - - bool isRange() const - { - return m_type == TokenType::Range; - } - - bool isKey() const - { - return m_type == TokenType::Key; - } - - bool isValid() const - { - return m_type != TokenType::Invalid; - } - - QString toString() const - { - QString str; - switch (m_type) { - case TokenType::Action: - str = QString("action %1").arg((int)m_action); - break; - - case TokenType::Repeat: - str = QString("repeat %1").arg(m_repeat); - break; - - case TokenType::Movement: - str = QString("movement %1").arg((int)m_movement); - break; - - case TokenType::Range: - str = QString("range %1").arg((int)m_range); - break; - - case TokenType::Key: - str = QString("key %1 %2").arg(m_key.m_key).arg(m_key.m_modifiers); - break; - - default: - str = "invalid"; - } - - return str; - } - - TokenType m_type; - - union - { - Action m_action; - int m_repeat; - Range m_range; - Movement m_movement; - }; - - // Used in some Movement and Key Token. - Key m_key; - }; - - // Stack for all the jump locations. - // When we execute a jump action, we push current location to the stack and - // remove older location with the same block number. - // Ctrl+O is also a jum action. If m_pointer points to the top of the stack, - // Ctrl+O will insert a location to the stack. - class LocationStack - { - public: - LocationStack(int p_maximum = 100); - - // Add @p_cursor's location to stack. - // Need to delete all older locations with the same block number. - void addLocation(const QTextCursor &p_cursor); - - // Go up through the stack. Need to add current location if we are at - // the top of the stack currently. - const Location &previousLocation(const QTextCursor &p_cursor); - - // Go down through the stack. - const Location &nextLocation(); - - bool hasPrevious() const; - - bool hasNext() const; - - private: - // A stack containing locations. - QList m_locations; - - // Pointer to current element in the stack. - // If we are not in the history of the locations, it points to the next - // element to the top element. - int m_pointer; - - // Maximum number of locations in stack. - const int c_maximumLocations; - }; - - enum IndentType { Indent = 0, UnIndent, AutoIndent }; - - // Returns true if the event is consumed and need no more handling. - bool handleKeyPressEvent(int key, int modifiers, int *p_autoIndentPos = NULL); - - // Reset all key state info. - void resetState(); - - // Now m_tokens constitute a command. Execute it. - // Will clear @p_tokens. - void processCommand(QList &p_tokens); - - // Return the number represented by @p_keys. - // Return -1 if @p_keys is not a valid digit sequence. - int numberFromKeySequence(const QList &p_keys); - - // Try to generate a Repeat token from @p_keys and insert it to @p_tokens. - // If succeed, clear @p_keys and return true. - bool tryGetRepeatToken(QList &p_keys, QList &p_tokens); - - // @p_tokens is the arguments of the Action::Move action. - void processMoveAction(QList &p_tokens); - - // @p_tokens is the arguments of the Action::Delete action. - void processDeleteAction(QList &p_tokens); - - // @p_tokens is the arguments of the Action::Copy action. - void processCopyAction(QList &p_tokens); - - // @p_tokens is the arguments of the Action::Paste and Action::PasteBefore action. - void processPasteAction(QList &p_tokens, bool p_pasteBefore); - - // @p_tokens is the arguments of the Action::Change action. - void processChangeAction(QList &p_tokens); - - // @p_tokens is the arguments of the Action::Indent, Action::UnIndent, - // and Action::AutoIndent action. - void processIndentAction(QList &p_tokens, IndentType p_type); - - // @p_tokens is the arguments of the Action::ToLower and Action::ToUpper action. - void processToLowerAction(QList &p_tokens, bool p_toLower); - - // @p_tokens is the arguments of the Action::Undo action. - void processUndoAction(QList &p_tokens); - - // @p_tokens is the arguments of the Action::Redo action. - void processRedoAction(QList &p_tokens); - - // @p_tokens is the arguments of the Action::RedrawAtBottom/RedrawAtCenter/RedrawAtTop action. - // @p_dest: 0 for top, 1 for center, 2 for bottom. - void processRedrawLineAction(QList &p_tokens, int p_dest); - - // Action::JumpPreviousLocation and Action::JumpNextLocation action. - void processJumpLocationAction(QList &p_tokens, bool p_next); - - // Action::Replace. - void processReplaceAction(QList &p_tokens); - - // Action::ReverseCase. - void processReverseCaseAction(QList &p_tokens); - - // Action::Join and Action::JoinNoModification action. - // @p_modifySpaces: whether remove the indent and insert up to two spaces. - void processJoinAction(QList &p_tokens, bool p_modifySpaces); - - // Clear selection if there is any. - // Returns true if there is selection. - bool clearSelection(); - - // Get the block count of one page step in vertical scroll bar. - int blockCountOfPageStep() const; - - // Expand selection to whole lines which will change the position - // of @p_cursor. - void expandSelectionToWholeLines(QTextCursor &p_cursor); - - // Init m_registers. - // Currently supported registers: - // a-z, A-Z (append to a-z), ", +, _ - void initRegisters(); - - // Check m_keys to see if we are expecting a register name. - bool expectingRegisterName() const; - - // Check m_keys to see if we are expecting a target for f/t/F/T command. - bool expectingCharacterTarget() const; - - // Check m_keys to see if we are expecting a character to replace with. - bool expectingReplaceCharacter() const; - - // Check if we are in a leader sequence. - bool expectingLeaderSequence() const; - - // Check m_keys to see if we are expecting a mark name to create a mark. - bool expectingMarkName() const; - - // Check m_keys to see if we are expecting a mark name as the target. - bool expectingMarkTarget() const; - - // Return the corresponding register name of @p_key. - // If @p_key is not a valid register name, return a NULL QChar. - QChar keyToRegisterName(const Key &p_key) const; - - // Check if @m_tokens contains an action token. - bool hasActionToken() const; - - // Check if @m_tokens contains a repeat token. - bool hasRepeatToken() const; - - // Try to add an Action::Move action at the front if there is no any action - // token. - void tryAddMoveAction(); - - // Add an Action token in front of m_tokens. - void addActionToken(Action p_action); - - // Get the action token from m_tokens. - const Token *getActionToken() const; - - // Get the repeat token from m_tokens. - Token *getRepeatToken(); - - // Add a Range token at the end of m_tokens. - void addRangeToken(Range p_range); - - // Add a Movement token at the end of m_tokens. - void addMovementToken(Movement p_movement); - - // Add a Movement token at the end of m_tokens. - void addMovementToken(Movement p_movement, Key p_key); - - // Add a Key token at the end of m_tokens. - void addKeyToken(Key p_key); - - // Delete selected text if there is any. - // @p_clearEmptyBlock: whether to remove the empty block after deletion. - void deleteSelectedText(QTextCursor &p_cursor, bool p_clearEmptyBlock); - - // Copy selected text if there is any. - // Will clear selection. - // @p_addNewLine: whether to add a new line \n to the selection. - void copySelectedText(bool p_addNewLine); - - void copySelectedText(QTextCursor &p_cursor, bool p_addNewLine); - - // Convert the case of selected text if there is any. - // Will clear selection. - // @p_toLower: to lower or upper. - void convertCaseOfSelectedText(QTextCursor &p_cursor, bool p_toLower); - - // Save @p_text to the Register pointed by m_regName. - // Remove QChar::ObjectReplacementCharacter before saving. - void saveToRegister(const QString &p_text); - - // Move @p_cursor according to @p_moveMode and @p_token. - // Return true if it has moved @p_cursor. - bool processMovement(QTextCursor &p_cursor, - QTextCursor::MoveMode p_moveMode, - const Token &p_token, - int p_repeat); - - // Move @p_cursor according to @p_moveMode and @p_range. - // Return true if it has moved @p_cursor. - bool selectRange(QTextCursor &p_cursor, const QTextDocument *p_doc, - Range p_range, int p_repeat); - - // Check if there is an Action token with Delete/Copy/Change action. - bool hasActionTokenValidForTextObject() const; - - // Check if m_keys only contains @p_key. - bool checkPendingKey(const Key &p_key) const; - - // Check if m_tokens only contains action token @p_action. - bool checkActionToken(Action p_action) const; - - // Repeat m_lastFindToken. - void repeatLastFindMovement(bool p_reverse); - - void message(const QString &p_str); - - // Check if m_mode equals to p_mode. - bool checkMode(VimMode p_mode); - - // Execute command specified by @p_cmd. - // @p_cmd does not contain the leading colon. - // Returns true if it is a valid command. - // Following commands are supported: - // w, wq, q, q!, x, - bool executeCommand(const QString &p_cmd); - - // Check if m_keys has non-digit key. - bool hasNonDigitPendingKeys(); - - bool hasNonDigitPendingKeys(const QList &p_keys); - - // Reading a leader sequence, read input @p_key and process it. - // Returns true if a sequence has been replayed or it is being read, - // otherwise returns false. - // Following sequences are supported: - // y: "+y - // d: "+d - // p: "+p - // P: "+P - bool processLeaderSequence(const Key &p_key); - - // Jump across titles. - // [[, ]], [], ][, [{, ]}. - void processTitleJump(const QList &p_tokens, bool p_forward, int p_relativeLevel); - - // Fetch the searched string and options from @p_type and @p_cmd. - // \C for case-sensitive; - // Case-insensitive by default. - // Regular-expression by default. - VVim::SearchItem fetchSearchItem(VVim::CommandLineType p_type, const QString &p_cmd); - - // Clear search highlight. - void clearSearchHighlight(); - - // Function utils for register. - Register &getRegister(QChar p_regName) const; - void setRegister(QChar p_regName, const QString &p_val); - - // May need to do these things: - // 1. Change the CursorBlock mode; - // 2. Alter the selection to assure the character in m_positionBeforeVisualMode - // is always selected. - void maintainSelectionInVisualMode(QTextCursor *p_cursor = NULL); - - void setCursorBlockMode(VEditor *p_cursor, CursorBlock p_mode); - - // Whether we should consider the left or right side of the cursor. - bool useLeftSideOfCursor(const QTextCursor &p_cursor); - - VEditor *m_editor; - const VEditConfig *m_editConfig; - VimMode m_mode; - - // A valid command token should follow the rule: - // Action, Repeat, Movement. - // Action, Repeat, Range. - // Action, Repeat. - QList m_keys; - QList m_tokens; - - // Keys for status indication. - QList m_pendingKeys; - - // Whether reset the position in block when moving cursor. - bool m_resetPositionInBlock; - - // Currently used register. - QChar m_regName; - - // Last f/F/t/T Token. - Token m_lastFindToken; - - // The leader key, which is Key_Space by default. - Key m_leaderKey; - - // Whether we are parsing a leader sequence. - // We will map a leader sequence to another actual sequence. When replaying - // this actual sequence, m_leaderSequence will be true. - bool m_replayLeaderSequence; - - LocationStack m_locations; - - Marks m_marks; - - // Search history. - SearchHistory m_searchHistory; - - // Whether we are expecting to read a register to insert. - bool m_registerPending; - - // Whether enter insert mode after a command. - bool m_insertModeAfterCommand; - - // Cursor position when entering Visual mode. - // After displaying cursor as block, we need to always select current character - // when entering Visual mode. - int m_positionBeforeVisualMode; - - static const QChar c_unnamedRegister; - static const QChar c_blackHoleRegister; - static const QChar c_selectionRegister; - - static QMap s_registers; -}; - -inline VVim::Register &VVim::getRegister(QChar p_regName) const -{ - return s_registers[p_regName]; -} - -inline void VVim::setRegister(QChar p_regName, const QString &p_val) -{ - s_registers[p_regName].update(p_val); -} -#endif // VVIM_H diff --git a/src/vattachmentlist.cpp b/src/vattachmentlist.cpp deleted file mode 100644 index cdc1d69c..00000000 --- a/src/vattachmentlist.cpp +++ /dev/null @@ -1,626 +0,0 @@ -#include "vattachmentlist.h" - -#include - -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "vbuttonwithwidget.h" -#include "vmainwindow.h" -#include "dialog/vconfirmdeletiondialog.h" -#include "dialog/vsortdialog.h" -#include "utils/vimnavigationforwidget.h" -#include "utils/viconutils.h" - -extern VConfigManager *g_config; -extern VMainWindow *g_mainWin; - -VAttachmentList::VAttachmentList(QWidget *p_parent) - : QWidget(p_parent), VButtonPopupWidget(this), m_file(NULL) -{ - setupUI(); - - initActions(); - - updateContent(); -} - -void VAttachmentList::setupUI() -{ - m_addBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/add_attachment.svg"), ""); - m_addBtn->setToolTip(tr("Add")); - m_addBtn->setProperty("FlatBtn", true); - m_addBtn->setDefault(true); - connect(m_addBtn, &QPushButton::clicked, - this, &VAttachmentList::addAttachment); - - m_clearBtn = new QPushButton(VIconUtils::buttonDangerIcon(":/resources/icons/clear_attachment.svg"), ""); - m_clearBtn->setToolTip(tr("Clear")); - m_clearBtn->setProperty("FlatBtn", true); - connect(m_clearBtn, &QPushButton::clicked, - this, [this]() { - if (m_file && m_attachmentList->count() > 0) { - int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Are you sure to clear attachments of note " - "%2?") - .arg(g_config->c_dataTextStyle) - .arg(m_file->getName()), - tr("WARNING: " - "VNote will delete all the files in directory " - "%3." - "Deleted files could be found in the recycle bin " - "of this note.
    The operation is IRREVERSIBLE!") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(m_file->fetchAttachmentFolderPath()), - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Ok, - g_mainWin, - MessageBoxType::Danger); - if (ret == QMessageBox::Ok) { - if (!m_file->deleteAttachments()) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to clear attachments of note %2.") - .arg(g_config->c_dataTextStyle) - .arg(m_file->getName()), - tr("Please check the attachments folder and " - "maintain the configuration file manually."), - QMessageBox::Ok, - QMessageBox::Ok, - g_mainWin); - } - - m_attachmentList->clear(); - - updateButtonState(); - } - } - }); - - m_locateBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/locate_attachment.svg"), ""); - m_locateBtn->setToolTip(tr("Open Folder")); - m_locateBtn->setProperty("FlatBtn", true); - connect(m_locateBtn, &QPushButton::clicked, - this, [this]() { - if (m_file && !m_file->getAttachmentFolder().isEmpty()) { - QUrl url = QUrl::fromLocalFile(m_file->fetchAttachmentFolderPath()); - QDesktopServices::openUrl(url); - } - }); - - m_numLabel = new QLabel(); - - QHBoxLayout *btnLayout = new QHBoxLayout; - btnLayout->addWidget(m_addBtn); - btnLayout->addWidget(m_clearBtn); - btnLayout->addWidget(m_locateBtn); - btnLayout->addStretch(); - btnLayout->addWidget(m_numLabel); - - m_attachmentList = new QListWidget; - m_attachmentList->setContextMenuPolicy(Qt::CustomContextMenu); - m_attachmentList->setSelectionMode(QAbstractItemView::ExtendedSelection); - m_attachmentList->setEditTriggers(QAbstractItemView::SelectedClicked); - m_attachmentList->setAttribute(Qt::WA_MacShowFocusRect, false); - m_attachmentList->setItemDelegate(&m_listDelegate); - connect(m_attachmentList, &QListWidget::customContextMenuRequested, - this, &VAttachmentList::handleContextMenuRequested); - connect(m_attachmentList, &QListWidget::itemActivated, - this, &VAttachmentList::handleItemActivated); - connect(m_attachmentList->itemDelegate(), &QAbstractItemDelegate::commitData, - this, &VAttachmentList::handleListItemCommitData); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(btnLayout); - mainLayout->addWidget(m_attachmentList); - - setLayout(mainLayout); -} - -void VAttachmentList::initActions() -{ - m_openAct = new QAction(tr("&Open"), this); - m_openAct->setToolTip(tr("Open current attachment file")); - connect(m_openAct, &QAction::triggered, - this, [this]() { - QListWidgetItem *item = m_attachmentList->currentItem(); - handleItemActivated(item); - }); - - m_deleteAct = new QAction(VIconUtils::menuDangerIcon(":/resources/icons/delete_attachment.svg"), - tr("&Delete"), - this); - m_deleteAct->setToolTip(tr("Delete selected attachments")); - connect(m_deleteAct, &QAction::triggered, - this, &VAttachmentList::deleteSelectedItems); - - m_sortAct = new QAction(VIconUtils::menuIcon(":/resources/icons/sort.svg"), - tr("&Sort"), - this); - m_sortAct->setToolTip(tr("Sort attachments manually")); - connect(m_sortAct, &QAction::triggered, - this, &VAttachmentList::sortItems); -} - -void VAttachmentList::setFile(VNoteFile *p_file) -{ - m_file = p_file; - - updateButtonState(); -} - -void VAttachmentList::updateContent() -{ - bool enableAdd = true, enableDelete = true, enableClear = true, enableLocate = true; - m_attachmentList->clear(); - - if (!m_file) { - enableAdd = enableDelete = enableClear = enableLocate = false; - } else { - QString folder = m_file->getAttachmentFolder(); - const QVector &attas = m_file->getAttachments(); - - if (folder.isEmpty()) { - Q_ASSERT(attas.isEmpty()); - enableDelete = enableClear = enableLocate = false; - } else if (attas.isEmpty()) { - enableDelete = enableClear = false; - } else { - fillAttachmentList(attas); - } - } - - m_addBtn->setEnabled(enableAdd); - m_clearBtn->setEnabled(enableClear); - m_locateBtn->setEnabled(enableLocate); - - int cnt = m_attachmentList->count(); - if (cnt > 0) { - m_numLabel->setText(tr("%1 %2").arg(cnt).arg(cnt > 1 ? tr("Files") : tr("File"))); - m_attachmentList->setFocus(); - } else { - m_numLabel->setText(""); - - if (m_file) { - m_addBtn->setFocus(); - } - } -} - -void VAttachmentList::fillAttachmentList(const QVector &p_attachments) -{ - Q_ASSERT(m_attachmentList->count() == 0); - for (int i = 0; i < p_attachments.size(); ++i) { - const VAttachment &atta = p_attachments[i]; - QListWidgetItem *item = new QListWidgetItem(atta.m_name); - item->setFlags(item->flags() | Qt::ItemIsEditable); - item->setData(Qt::UserRole, atta.m_name); - - m_attachmentList->addItem(item); - } -} - -void VAttachmentList::addAttachment() -{ - if (!m_file) { - return; - } - - static QString lastPath = QDir::homePath(); - QStringList files = QFileDialog::getOpenFileNames(g_mainWin, - tr("Select Files As Attachments"), - lastPath); - if (files.isEmpty()) { - return; - } - - // Update lastPath - lastPath = QFileInfo(files[0]).path(); - - addAttachments(files); - - updateButtonState(); - - updateContent(); -} - -void VAttachmentList::addAttachments(const QStringList &p_files) -{ - Q_ASSERT(m_file); - int addedFiles = 0; - for (int i = 0; i < p_files.size(); ++i) { - if (!m_file->addAttachment(p_files[i])) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to add attachment %1 for note %3.") - .arg(p_files[i]) - .arg(g_config->c_dataTextStyle) - .arg(m_file->getName()), - "", - QMessageBox::Ok, - QMessageBox::Ok, - g_mainWin); - } else { - ++addedFiles; - } - } - - if (addedFiles > 0) { - g_mainWin->showStatusMessage(tr("%1 %2 added as attachments") - .arg(addedFiles) - .arg(addedFiles > 1 ? tr("files") : tr("file"))); - } -} - -void VAttachmentList::handleContextMenuRequested(QPoint p_pos) -{ - // @p_pos is the position in the coordinate of VAttachmentList, no m_attachmentList. - QListWidgetItem *item = m_attachmentList->itemAt(m_attachmentList->mapFromParent(p_pos)); - QMenu menu(this); - menu.setToolTipsVisible(true); - - if (!m_file) { - return; - } - - if (item) { - if (!item->isSelected()) { - m_attachmentList->setCurrentItem(item, QItemSelectionModel::ClearAndSelect); - } - - if (m_attachmentList->selectedItems().size() == 1) { - menu.addAction(m_openAct); - } - - menu.addAction(m_deleteAct); - } - - m_attachmentList->update(); - - if (m_file->getAttachments().size() > 1) { - if (!menu.actions().isEmpty()) { - menu.addSeparator(); - } - - menu.addAction(m_sortAct); - } - - if (!menu.actions().isEmpty()) { - menu.exec(mapToGlobal(p_pos)); - } -} - -void VAttachmentList::handleItemActivated(QListWidgetItem *p_item) -{ - if (p_item) { - Q_ASSERT(m_file); - - QString name = p_item->text(); - QString folderPath = m_file->fetchAttachmentFolderPath(); - QUrl url = QUrl::fromLocalFile(QDir(folderPath).filePath(name)); - QDesktopServices::openUrl(url); - } -} - -void VAttachmentList::deleteSelectedItems() -{ - QVector items; - const QList selectedItems = m_attachmentList->selectedItems(); - - if (selectedItems.isEmpty()) { - return; - } - - for (auto const & item : selectedItems) { - items.push_back(ConfirmItemInfo(item->text(), - item->text(), - "", - NULL)); - } - - QString text = tr("Are you sure to delete these attachments of note " - "%2?") - .arg(g_config->c_dataTextStyle).arg(m_file->getName()); - - QString info = tr("Deleted files could be found in the recycle " - "bin of this note.
    " - "Click \"Cancel\" to leave them untouched."); - - VConfirmDeletionDialog dialog(tr("Confirm Deleting Attachments"), - text, - info, - items, - false, - false, - false, - g_mainWin); - if (dialog.exec()) { - items = dialog.getConfirmedItems(); - - QVector names; - for (auto const & item : items) { - names.push_back(item.m_name); - } - - if (!m_file->deleteAttachments(names)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to delete attachments of note %2.") - .arg(g_config->c_dataTextStyle) - .arg(m_file->getName()), - tr("Please check the attachments folder and " - "maintain the configuration file manually."), - QMessageBox::Ok, - QMessageBox::Ok, - g_mainWin); - } - - updateButtonState(); - - updateContent(); - } -} - -void VAttachmentList::sortItems() -{ - const QVector &attas = m_file->getAttachments(); - if (attas.size() < 2) { - return; - } - - VSortDialog dialog(tr("Sort Attachments"), - tr("Sort attachments of note %2 " - "in the configuration file.") - .arg(g_config->c_dataTextStyle) - .arg(m_file->getName()), - g_mainWin); - QTreeWidget *tree = dialog.getTreeWidget(); - tree->clear(); - tree->setColumnCount(1); - QStringList headers; - headers << tr("Name"); - tree->setHeaderLabels(headers); - - for (int i = 0; i < attas.size(); ++i) { - QTreeWidgetItem *item = new QTreeWidgetItem(tree, QStringList(attas[i].m_name)); - - item->setData(0, Qt::UserRole, i); - } - - dialog.treeUpdated(); - - if (dialog.exec()) { - QVector data = dialog.getSortedData(); - Q_ASSERT(data.size() == attas.size()); - QVector sortedIdx(data.size(), -1); - for (int i = 0; i < data.size(); ++i) { - sortedIdx[i] = data[i].toInt(); - } - - if (!m_file->sortAttachments(sortedIdx)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to sort attachments of note %2.") - .arg(g_config->c_dataTextStyle) - .arg(m_file->getName()), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - } -} - -void VAttachmentList::handleListItemCommitData(QWidget *p_itemEdit) -{ - QString text = reinterpret_cast(p_itemEdit)->text(); - QListWidgetItem *item = m_attachmentList->currentItem(); - Q_ASSERT(item && item->text() == text); - - QString oldText = item->data(Qt::UserRole).toString(); - - if (oldText == text) { - return; - } - - bool legalName = true; - if (text.isEmpty()) { - legalName = false; - } else { - QRegExp reg(VUtils::c_fileNameRegExp); - if (!reg.exactMatch(text)) { - legalName = false; - } - } - - if (!legalName) { - // Recover to old name. - item->setText(oldText); - return; - } - - if (!(oldText.toLower() == text.toLower()) - && m_file->findAttachment(text, false) > -1) { - // Name conflict. - // Recover to old name. - item->setText(oldText); - } else { - if (!m_file->renameAttachment(oldText, text)) { - VUtils::showMessage(QMessageBox::Information, - tr("Rename Attachment"), - tr("Fail to rename attachment %2.") - .arg(g_config->c_dataTextStyle) - .arg(oldText), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - // Recover to old name. - item->setText(oldText); - } else { - // Change the data. - item->setData(Qt::UserRole, text); - } - } -} - -void VAttachmentList::keyPressEvent(QKeyEvent *p_event) -{ - if (VimNavigationForWidget::injectKeyPressEventForVim(m_attachmentList, - p_event, - this)) { - return; - } - - QWidget::keyPressEvent(p_event); -} - -bool VAttachmentList::isAcceptDrops() const -{ - return true; -} - -bool VAttachmentList::handleDragEnterEvent(QDragEnterEvent *p_event) -{ - if (!m_file) { - return false; - } - - if (p_event->mimeData()->hasFormat("text/uri-list")) { - p_event->acceptProposedAction(); - return true; - } - - return false; -} - -bool VAttachmentList::handleDropEvent(QDropEvent *p_event) -{ - if (!m_file) { - return false; - } - - const QMimeData *mime = p_event->mimeData(); - if (mime->hasFormat("text/uri-list") && mime->hasUrls()) { - // Add attachments. - QStringList files; - QList urls = mime->urls(); - for (int i = 0; i < urls.size(); ++i) { - QString file; - if (urls[i].isLocalFile()) { - file = urls[i].toLocalFile(); - QFileInfo fi(file); - if (fi.exists() && fi.isFile()) { - file = QDir::cleanPath(fi.absoluteFilePath()); - files.append(file); - } - } - } - - if (!files.isEmpty()) { - addAttachments(files); - - updateButtonState(); - } - - p_event->acceptProposedAction(); - return true; - } - - return false; -} - -void VAttachmentList::handleAboutToShow() -{ - updateContent(); - - checkAttachments(); -} - -void VAttachmentList::updateButtonState() const -{ - VButtonWithWidget *btn = getButton(); - Q_ASSERT(btn); - if (!btn) { - return; - } - - int numOfAttachments = -1; - if (m_file) { - numOfAttachments = m_file->getAttachments().size(); - if (numOfAttachments == 0) { - numOfAttachments = -1; - } - } - - btn->setBubbleNumber(numOfAttachments); -} - -void VAttachmentList::checkAttachments() -{ - if (!m_file) { - return; - } - - QVector missingAttas = m_file->checkAttachments(); - if (missingAttas.isEmpty()) { - return; - } - - QVector items; - for (auto const & atta : missingAttas) { - items.push_back(ConfirmItemInfo(atta, - atta, - "", - NULL)); - } - - QString text = tr("VNote detects that these attachments of note " - "%2 are missing in disk. " - "Would you like to remove them from the note?") - .arg(g_config->c_dataTextStyle) - .arg(m_file->getName()); - - QString info = tr("Click \"Cancel\" to leave them untouched."); - - VConfirmDeletionDialog dialog(tr("Confirm Deleting Attachments"), - text, - info, - items, - false, - false, - false, - g_mainWin); - if (dialog.exec()) { - items = dialog.getConfirmedItems(); - - QVector names; - for (auto const & item : items) { - names.push_back(item.m_name); - } - - if (!m_file->deleteAttachments(names, true)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to delete attachments of note %2.") - .arg(g_config->c_dataTextStyle) - .arg(m_file->getName()), - tr("Please check the attachments folder and " - "maintain the configuration file manually."), - QMessageBox::Ok, - QMessageBox::Ok, - g_mainWin); - } - - updateButtonState(); - - updateContent(); - } -} - -void VAttachmentList::showEvent(QShowEvent *p_event) -{ - QWidget::showEvent(p_event); - - processShowEvent(p_event); -} diff --git a/src/vattachmentlist.h b/src/vattachmentlist.h deleted file mode 100644 index 025a5a03..00000000 --- a/src/vattachmentlist.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef VATTACHMENTLIST_H -#define VATTACHMENTLIST_H - -#include -#include -#include -#include "vnotefile.h" -#include "vbuttonwithwidget.h" -#include "lineeditdelegate.h" - -class QPushButton; -class QListWidget; -class QListWidgetItem; -class QLabel; -class VNoteFile; -class QAction; - - -class VAttachmentList : public QWidget, public VButtonPopupWidget -{ - Q_OBJECT -public: - explicit VAttachmentList(QWidget *p_parent = 0); - - // Need to call updateContent() to update the list. - void setFile(VNoteFile *p_file); - - // Update attachment info of m_file. - void updateContent(); - - bool isAcceptDrops() const Q_DECL_OVERRIDE; - - bool handleDragEnterEvent(QDragEnterEvent *p_event) Q_DECL_OVERRIDE; - - bool handleDropEvent(QDropEvent *p_event) Q_DECL_OVERRIDE; - - void handleAboutToShow() Q_DECL_OVERRIDE; - -protected: - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - void addAttachment(); - - void handleContextMenuRequested(QPoint p_pos); - - void handleItemActivated(QListWidgetItem *p_item); - - void deleteSelectedItems(); - - void sortItems(); - - void handleListItemCommitData(QWidget *p_itemEdit); - -private: - void setupUI(); - - void initActions(); - - void fillAttachmentList(const QVector &p_attachments); - - void addAttachments(const QStringList &p_files); - - // Update the state of VButtonWithWidget. - void updateButtonState() const; - - // Check if there are attachments that do not exist in disk. - void checkAttachments(); - - QPushButton *m_addBtn; - QPushButton *m_clearBtn; - QPushButton *m_locateBtn; - QLabel *m_numLabel; - - LineEditDelegate m_listDelegate; - QListWidget *m_attachmentList; - - QAction *m_openAct; - QAction *m_deleteAct; - QAction *m_sortAct; - - VNoteFile *m_file; -}; - -#endif // VATTACHMENTLIST_H diff --git a/src/vavatar.cpp b/src/vavatar.cpp deleted file mode 100644 index 8d89389d..00000000 --- a/src/vavatar.cpp +++ /dev/null @@ -1,117 +0,0 @@ -#include "vavatar.h" -#include -#include -#include -#include -#include -#include - -VAvatar::VAvatar(QWidget *p_parent) - : QWidget(p_parent, Qt::FramelessWindowHint | Qt::WindowSystemMenuHint), - m_avatarText("VN"), m_diameter(48), m_borderWidth(3) -{ - resize(m_diameter, m_diameter); -} - -void VAvatar::paintEvent(QPaintEvent * /*p_event*/) -{ - int diameter = width(); - int x = diameter / 2; - int y = x + 1; - - // Border - QPainterPath path; - path.addEllipse(QPoint(x, y), x - m_borderWidth, y - m_borderWidth); - - QPainter painter(this); - painter.setClipPath(path); - painter.setClipping(true); - painter.setRenderHint(QPainter::Antialiasing); - - if (!m_avatarPixmap.isEmpty()) { - drawPixmap(painter); - } else { - drawText(painter, x); - } - drawBorder(painter, path); -} - -void VAvatar::drawPixmap(QPainter &p_painter) -{ - p_painter.drawPixmap(rect(), m_pixmap); -} - -void VAvatar::drawText(QPainter &p_painter, int p_fontPixcel) -{ - p_painter.save(); - QFont font = p_painter.font(); - font.setPixelSize(p_fontPixcel); - p_painter.setPen(m_fgColor); - p_painter.setFont(font); - p_painter.drawText(rect(), Qt::AlignCenter, m_avatarText); - p_painter.restore(); -} - -void VAvatar::drawBorder(QPainter &p_painter, const QPainterPath &p_path) -{ - p_painter.save(); - p_painter.setClipping(false); - QPen borderPen(m_baseColor); - borderPen.setWidth(m_borderWidth); - p_painter.setPen(borderPen); - p_painter.drawPath(p_path); - p_painter.restore(); -} - -void VAvatar::setDiameter(int p_diameter) -{ - if (m_diameter == p_diameter) { - return; - } - m_diameter = p_diameter; - resize(m_diameter, m_diameter); -} - -void VAvatar::setAvatarText(const QString &p_avatarText) -{ - if (m_avatarText == p_avatarText) { - return; - } - m_avatarText = p_avatarText.left(2); - m_avatarPixmap.clear(); - update(); -} - -void VAvatar::setAvatarPixmap(const QString &p_avatarPixmap) -{ - if (m_avatarPixmap == p_avatarPixmap) { - return; - } - m_avatarPixmap = p_avatarPixmap; - m_pixmap = QPixmap(m_avatarPixmap); - m_avatarText.clear(); - update(); -} - -QSize VAvatar::sizeHint() const -{ - return QSize(m_diameter, m_diameter); -} - -void VAvatar::setColor(const QString &p_baseColor, const QString &p_fgColor, const QString &p_bgColor) -{ - m_baseColor.setNamedColor(p_baseColor); - m_fgColor.setNamedColor(p_fgColor); - m_bgColor.setNamedColor(p_bgColor); -} - -void VAvatar::updateBaseColor(const QString &p_baseColor) -{ - m_baseColor.setNamedColor(p_baseColor); - update(); -} - -QString VAvatar::getBaseColor() const -{ - return m_baseColor.name(); -} diff --git a/src/vavatar.h b/src/vavatar.h deleted file mode 100644 index deeb83c6..00000000 --- a/src/vavatar.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef VAVATAR_H -#define VAVATAR_H - -#include -#include -#include -#include - -class QLabel; - -class VAvatar : public QWidget -{ - Q_OBJECT -public: - explicit VAvatar(QWidget *p_parent = 0); - void setDiameter(int p_diameter); - void setAvatarPixmap(const QString &p_avatarPixmap); - void setAvatarText(const QString &p_avatarText); - void setColor(const QString &p_baseColor, const QString &p_fgColor, const QString &p_bgColor); - void updateBaseColor(const QString &p_baseColor); - QSize sizeHint() const Q_DECL_OVERRIDE; - QString getBaseColor() const; - -protected: - void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; - -private: - void drawPixmap(QPainter &p_painter); - void drawText(QPainter &p_painter, int p_fontPixcel); - void drawBorder(QPainter &p_painter, const QPainterPath &p_path); - - // Draw a pixmap or characters. - QString m_avatarPixmap; - QString m_avatarText; - int m_diameter; - QColor m_baseColor; - QColor m_fgColor; - QColor m_bgColor; - int m_borderWidth; - QPixmap m_pixmap; -}; - -#endif // VAVATAR_H diff --git a/src/vbuttonmenuitem.cpp b/src/vbuttonmenuitem.cpp deleted file mode 100644 index a0914b1c..00000000 --- a/src/vbuttonmenuitem.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "vbuttonmenuitem.h" - -#include -#include -#include -#include -#include - -VButtonMenuItem::VButtonMenuItem(QAction *p_action, QWidget *p_parent) - : QPushButton(p_parent), - m_action(p_action), - m_decorationWidth(0) -{ - init(); -} - -VButtonMenuItem::VButtonMenuItem(QAction *p_action, const QString &p_text, QWidget *p_parent) - : QPushButton(p_text, p_parent), - m_action(p_action), - m_decorationWidth(0) -{ - init(); -} - -VButtonMenuItem::VButtonMenuItem(QAction *p_action, - const QIcon &p_icon, - const QString &p_text, - const QString &p_decorationText, - QWidget *p_parent) - : QPushButton(p_icon, p_text, p_parent), - m_action(p_action), - m_decorationText(p_decorationText), - m_decorationWidth(0) -{ - init(); -} - -void VButtonMenuItem::init() -{ - connect(this, &QPushButton::clicked, - m_action, &QAction::triggered); -} - -void VButtonMenuItem::paintEvent(QPaintEvent *p_event) -{ - QPushButton::paintEvent(p_event); - - if (m_decorationWidth > 0) { - Q_ASSERT(!m_decorationText.isEmpty()); - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - QFont font = painter.font(); - font.setItalic(true); - painter.setFont(font); - - QRect re = rect(); - re.adjust(re.width() - m_decorationWidth, 0, 0, 0); - painter.drawText(re, Qt::AlignCenter, m_decorationText); - } -} - -QSize VButtonMenuItem::sizeHint() const -{ - QSize size = QPushButton::sizeHint(); - if (!m_decorationText.isEmpty()) { - const_cast(this)->m_decorationWidth = 5 + fontMetrics().width(m_decorationText); - size.rwidth() += m_decorationWidth; - } - - return size; -} diff --git a/src/vbuttonmenuitem.h b/src/vbuttonmenuitem.h deleted file mode 100644 index 4324b130..00000000 --- a/src/vbuttonmenuitem.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef VBUTTONMENUITEM_H -#define VBUTTONMENUITEM_H - -#include - -class QAction; -class QPaintEvent; - - -class VButtonMenuItem : public QPushButton -{ - Q_OBJECT -public: - explicit VButtonMenuItem(QAction *p_action, QWidget *p_parent = nullptr); - - VButtonMenuItem(QAction *p_action, const QString &p_text, QWidget *p_parent = nullptr); - - VButtonMenuItem(QAction *p_action, - const QIcon &p_icon, - const QString &p_text, - const QString &p_decorationText = QString(), - QWidget *p_parent = nullptr); - - QSize sizeHint() const Q_DECL_OVERRIDE; - -protected: - void paintEvent(QPaintEvent *p_event) Q_DECL_OVERRIDE; - -private: - void init(); - - QAction *m_action; - - // Decoration text drawn at the right end. - QString m_decorationText; - - // Width in pixels of the decoration text. - int m_decorationWidth; -}; - -#endif // VBUTTONMENUITEM_H diff --git a/src/vbuttonwithwidget.cpp b/src/vbuttonwithwidget.cpp deleted file mode 100644 index 2f036dff..00000000 --- a/src/vbuttonwithwidget.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include "vbuttonwithwidget.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -VButtonWithWidget::VButtonWithWidget(QWidget *p_widget, - QWidget *p_parent) - : QPushButton(p_parent), m_popupWidget(p_widget) -{ - init(); -} - -VButtonWithWidget::VButtonWithWidget(const QString &p_text, - QWidget *p_widget, - QWidget *p_parent) - : QPushButton(p_text, p_parent), m_popupWidget(p_widget) -{ - init(); -} - -VButtonWithWidget::VButtonWithWidget(const QIcon &p_icon, - const QString &p_text, - QWidget *p_widget, - QWidget *p_parent) - : QPushButton(p_icon, p_text, p_parent), m_popupWidget(p_widget) -{ - init(); -} - -void VButtonWithWidget::init() -{ - m_popupWidget->setParent(this); - - m_bubbleFg = QColor(Qt::white); - m_bubbleBg = QColor("#15AE67"); - - QMenu *menu = new QMenu(this); - QWidgetAction *act = new QWidgetAction(menu); - act->setDefaultWidget(m_popupWidget); - menu->addAction(act); - connect(menu, &QMenu::aboutToShow, - this, [this]() { - emit popupWidgetAboutToShow(m_popupWidget); - }); - - setMenu(menu); - - VButtonPopupWidget *popup = getButtonPopupWidget(); - if (popup) { - popup->setButton(this); - setAcceptDrops(popup->isAcceptDrops()); - connect(this, &VButtonWithWidget::popupWidgetAboutToShow, - this, [this]() { - getButtonPopupWidget()->handleAboutToShow(); - }); - } -} - -QWidget *VButtonWithWidget::getPopupWidget() const -{ - return m_popupWidget; -} - -void VButtonWithWidget::showPopupWidget() -{ - showMenu(); -} - -void VButtonWithWidget::dragEnterEvent(QDragEnterEvent *p_event) -{ - VButtonPopupWidget *popup = getButtonPopupWidget(); - Q_ASSERT(popup); - - if (popup->handleDragEnterEvent(p_event)) { - return; - } - - QPushButton::dragEnterEvent(p_event); -} - -void VButtonWithWidget::dropEvent(QDropEvent *p_event) -{ - VButtonPopupWidget *popup = getButtonPopupWidget(); - Q_ASSERT(popup); - - if (popup->handleDropEvent(p_event)) { - return; - } - - QPushButton::dropEvent(p_event); -} - -void VButtonWithWidget::paintEvent(QPaintEvent *p_event) -{ - QPushButton::paintEvent(p_event); - - if (!isEnabled() || m_bubbleStr.isEmpty()) { - return; - } - - QRect re = rect(); - int bubbleWidth = re.width() * 3.0 / 7; - int x = re.width() - bubbleWidth; - int y = 0; - QRect bubbleRect(x, y, bubbleWidth, bubbleWidth); - - QPainter painter(this); - QPainterPath bgPath; - bgPath.addEllipse(bubbleRect); - painter.fillPath(bgPath, m_bubbleBg); - - QFont font = painter.font(); - font.setPixelSize(bubbleWidth / 1.3); - painter.setFont(font); - painter.setPen(m_bubbleFg); - painter.drawText(bubbleRect, Qt::AlignCenter, m_bubbleStr); -} - -void VButtonWithWidget::setBubbleNumber(int p_num) -{ - if (p_num < 0) { - m_bubbleStr.clear(); - } else { - m_bubbleStr = QString::number(p_num); - } - - update(); -} diff --git a/src/vbuttonwithwidget.h b/src/vbuttonwithwidget.h deleted file mode 100644 index e9f54fb9..00000000 --- a/src/vbuttonwithwidget.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef VBUTTONWITHWIDGET_H -#define VBUTTONWITHWIDGET_H - -#include -#include -#include -#include - -class QDragEnterEvent; -class QDropEvent; -class QPaintEvent; -class QShowEvent; -class VButtonWithWidget; - -// Abstract class for the widget used by VButtonWithWidget. -// Widget need to inherit this class if drag/drop is needed. -class VButtonPopupWidget -{ -public: - VButtonPopupWidget(QWidget *p_widget) - : m_widget(p_widget), m_btn(NULL) - { - } - - virtual bool isAcceptDrops() const = 0; - virtual bool handleDragEnterEvent(QDragEnterEvent *p_event) = 0; - virtual bool handleDropEvent(QDropEvent *p_event) = 0; - virtual void handleAboutToShow() = 0; - - void setButton(VButtonWithWidget *p_btn) - { - m_btn = p_btn; - } - - VButtonWithWidget *getButton() const - { - return m_btn; - } - -protected: - // **MUST** be called in subclass at the end of showEvent(). - void processShowEvent(QShowEvent *p_event) - { - Q_UNUSED(p_event); - m_widget->activateWindow(); - } - -private: - QWidget *m_widget; - - VButtonWithWidget *m_btn; -}; - -// A QPushButton with popup widget. -class VButtonWithWidget : public QPushButton -{ - Q_OBJECT -public: - VButtonWithWidget(QWidget *p_widget, - QWidget *p_parent = Q_NULLPTR); - - VButtonWithWidget(const QString &p_text, - QWidget *p_widget, - QWidget *p_parent = Q_NULLPTR); - - VButtonWithWidget(const QIcon &p_icon, - const QString &p_text, - QWidget *p_widget, - QWidget *p_parent = Q_NULLPTR); - - QWidget *getPopupWidget() const; - - // Show the popup widget. - void showPopupWidget(); - - // Set the bubble to display a number @p_num. - // @p_num: -1 to hide the bubble. - void setBubbleNumber(int p_num); - - // Set the foreground and background of the bubble. - void setBubbleColor(const QColor &p_fg, const QColor &p_bg); - -signals: - // Emit when popup widget is about to show. - void popupWidgetAboutToShow(QWidget *p_widget); - -protected: - // To accept specific drop. - void dragEnterEvent(QDragEnterEvent *p_event) Q_DECL_OVERRIDE; - - // Drop the data. - void dropEvent(QDropEvent *p_event) Q_DECL_OVERRIDE; - - void paintEvent(QPaintEvent *p_event) Q_DECL_OVERRIDE; - -private: - void init(); - - // Get VButtonWithWidget from m_popupWidget. - VButtonPopupWidget *getButtonPopupWidget() const; - - QWidget *m_popupWidget; - - QColor m_bubbleBg; - QColor m_bubbleFg; - - // String to display in the bubble. - // Empty to hide bubble. - QString m_bubbleStr; -}; - -inline VButtonPopupWidget *VButtonWithWidget::getButtonPopupWidget() const -{ - return dynamic_cast(m_popupWidget); -} - -inline void VButtonWithWidget::setBubbleColor(const QColor &p_fg, const QColor &p_bg) -{ - m_bubbleFg = p_fg; - m_bubbleBg = p_bg; -} -#endif // VBUTTONWITHWIDGET_H diff --git a/src/vcaptain.cpp b/src/vcaptain.cpp deleted file mode 100644 index 916d5e21..00000000 --- a/src/vcaptain.cpp +++ /dev/null @@ -1,282 +0,0 @@ -#include -#include -#include -#include -#include "vcaptain.h" -#include "veditarea.h" -#include "vedittab.h" -#include "vfilelist.h" -#include "vnavigationmode.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -VCaptain::VCaptain(QWidget *p_parent) - : QWidget(p_parent), - m_mode(CaptainMode::Normal), - m_widgetBeforeCaptain(NULL), - m_nextMajorKey('a'), - m_ignoreFocusChange(false) -{ - connect(qApp, &QApplication::focusChanged, - this, &VCaptain::handleFocusChanged); - - setWindowFlags(Qt::FramelessWindowHint); - - // Make it as small as possible. This widget will stay at the top-left corner - // of VMainWindow. - resize(1, 1); - - // Register Captain mode leader key. - // This can fix the Input Method blocking issue. - QShortcut *shortcut = new QShortcut(QKeySequence(g_config->getShortcutKeySequence("CaptainMode")), - this); - shortcut->setContext(Qt::ApplicationShortcut); - connect(shortcut, &QShortcut::activated, - this, &VCaptain::trigger); - - // Register Navigation mode as Captain mode target. - registerCaptainTarget(tr("NavigationMode"), - g_config->getCaptainShortcutKeySequence("NavigationMode"), - this, - navigationModeByCaptain); -} - -QChar VCaptain::getNextMajorKey() -{ - QChar ret = m_nextMajorKey; - if (m_nextMajorKey == 'z') { - m_nextMajorKey = QChar(); - } else if (!m_nextMajorKey.isNull()) { - m_nextMajorKey = QChar(m_nextMajorKey.toLatin1() + 1); - } - return ret; -} - -void VCaptain::registerNavigationTarget(VNavigationMode *p_target) -{ - QChar key = getNextMajorKey(); - if (!key.isNull()) { - p_target->registerNavigation(key); - m_naviTargets.push_back(NaviModeTarget(p_target, true)); - } -} - -void VCaptain::handleFocusChanged(QWidget *p_old, QWidget * p_now) -{ - Q_UNUSED(p_now); - - if (p_old == this - && !m_ignoreFocusChange - && !checkMode(CaptainMode::Normal)) { - exitCaptainMode(); - } -} - -void VCaptain::trigger() -{ - if (!checkMode(CaptainMode::Normal)) { - exitCaptainMode(); - return; - } - - triggerCaptainMode(); -} - -void VCaptain::keyPressEvent(QKeyEvent *p_event) -{ - int key = p_event->key(); - Qt::KeyboardModifiers modifiers = p_event->modifiers(); - - Q_ASSERT(!checkMode(CaptainMode::Normal)); - - if (VUtils::isMetaKey(key)) { - QWidget::keyPressEvent(p_event); - return; - } - - if (handleKeyPress(key, modifiers)) { - p_event->accept(); - } else { - QWidget::keyPressEvent(p_event); - } -} - -bool VCaptain::handleKeyPress(int p_key, Qt::KeyboardModifiers p_modifiers) -{ - bool ret = true; - - m_ignoreFocusChange = true; - - if (checkMode(CaptainMode::Navigation)) { - ret = handleKeyPressNavigationMode(p_key, p_modifiers); - m_ignoreFocusChange = false; - return ret; - } - - ret = handleKeyPressCaptainMode(p_key, p_modifiers); - m_ignoreFocusChange = false; - return ret; -} - -bool VCaptain::handleKeyPressNavigationMode(int p_key, - Qt::KeyboardModifiers /* p_modifiers */) -{ - Q_ASSERT(m_mode == CaptainMode::Navigation); - bool hasConsumed = false; - bool pending = false; - for (auto &target : m_naviTargets) { - if (hasConsumed) { - target.m_available = false; - target.m_target->hideNavigation(); - continue; - } - if (target.m_available) { - bool succeed = false; - // May change focus, so we need to ignore focus change here. - bool consumed = target.m_target->handleKeyNavigation(p_key, succeed); - if (consumed) { - hasConsumed = true; - if (succeed) { - // Exit. - m_widgetBeforeCaptain = NULL; - } else { - // Consumed but not succeed. Need more keys. - pending = true; - } - } else { - // Do not ask this target any more. - target.m_available = false; - target.m_target->hideNavigation(); - } - } - } - - if (pending) { - return true; - } - - exitCaptainMode(); - return true; -} - -void VCaptain::triggerNavigationMode() -{ - setMode(CaptainMode::Navigation); - - for (auto &target : m_naviTargets) { - target.m_available = true; - target.m_target->showNavigation(); - } -} - -void VCaptain::exitNavigationMode() -{ - setMode(CaptainMode::Normal); - - for (auto &target : m_naviTargets) { - target.m_available = true; - target.m_target->hideNavigation(); - } -} - -void VCaptain::restoreFocus() -{ - if (m_widgetBeforeCaptain) { - m_widgetBeforeCaptain->setFocus(); - m_widgetBeforeCaptain = NULL; - } -} - -void VCaptain::exitCaptainMode() -{ - if (checkMode(CaptainMode::Navigation)) { - exitNavigationMode(); - } - - setMode(CaptainMode::Normal); - m_ignoreFocusChange = false; - - restoreFocus(); - - emit captainModeChanged(false); -} - -bool VCaptain::registerCaptainTarget(const QString &p_name, - const QString &p_key, - void *p_target, - CaptainFunc p_func) -{ - if (p_key.isEmpty()) { - return false; - } - - QString normKey = QKeySequence(p_key).toString(); - - if (m_captainTargets.contains(normKey)) { - return false; - } - - CaptainModeTarget target(p_name, - normKey, - p_target, - p_func); - m_captainTargets.insert(normKey, target); - - qDebug() << "registered:" << target.toString() << normKey; - - return true; -} - -void VCaptain::triggerCaptainTarget(const QString &p_key) -{ - auto it = m_captainTargets.find(p_key); - if (it == m_captainTargets.end()) { - return; - } - - const CaptainModeTarget &target = it.value(); - - qDebug() << "triggered:" << target.toString(); - - CaptainData data(m_widgetBeforeCaptain); - if (!target.m_function(target.m_target, (void *)&data)) { - m_widgetBeforeCaptain = NULL; - } -} - -bool VCaptain::navigationModeByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VCaptain *obj = static_cast(p_target); - obj->triggerNavigationMode(); - return true; -} - -void VCaptain::triggerCaptainMode() -{ - m_widgetBeforeCaptain = QApplication::focusWidget(); - - m_ignoreFocusChange = false; - - setMode(CaptainMode::Pending); - - emit captainModeChanged(true); - - // Focus to listen pending key press. - setFocus(); -} - -bool VCaptain::handleKeyPressCaptainMode(int p_key, - Qt::KeyboardModifiers p_modifiers) -{ - Q_ASSERT(checkMode(CaptainMode::Pending)); - QString normKey = QKeySequence(p_key | p_modifiers).toString(); - triggerCaptainTarget(normKey); - - if (!checkMode(CaptainMode::Navigation)) { - exitCaptainMode(); - } - - return true; -} diff --git a/src/vcaptain.h b/src/vcaptain.h deleted file mode 100644 index 15d4670f..00000000 --- a/src/vcaptain.h +++ /dev/null @@ -1,186 +0,0 @@ -#ifndef VCAPTAIN_H -#define VCAPTAIN_H - -#include - -#include -#include -#include - -class QKeyEvent; -class VNavigationMode; -class QShortcut; - -// bool func(void *p_target, void *p_data); -// Return true if the target needs to restore focus by the Captain. -typedef std::function CaptainFunc; - - -// Will be passed to CaptainFunc as the data. -struct CaptainData -{ - CaptainData(QWidget *p_focusWidgetBeforeCaptain) - : m_focusWidgetBeforeCaptain(p_focusWidgetBeforeCaptain) - { - } - - QWidget *m_focusWidgetBeforeCaptain; -}; - - -class VCaptain : public QWidget -{ - Q_OBJECT -public: - explicit VCaptain(QWidget *p_parent); - - // Register a target for Navigation mode. - void registerNavigationTarget(VNavigationMode *p_target); - - // Register a target for Captain mode. - bool registerCaptainTarget(const QString &p_name, - const QString &p_key, - void *p_target, - CaptainFunc p_func); - -signals: - // Emit when mode changed. - void captainModeChanged(bool p_captainMode); - -protected: - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - // Exit Navigation mode if focus lost. - void handleFocusChanged(QWidget *p_old, QWidget *p_new); - -private: - // A widget target for Navigation mode. - struct NaviModeTarget { - NaviModeTarget() - : m_target(nullptr), m_available(false) - { - } - - NaviModeTarget(VNavigationMode *p_target, bool p_available) - : m_target(p_target), m_available(p_available) - { - } - - VNavigationMode *m_target; - bool m_available; - }; - - // Modes. - enum class CaptainMode { - Normal = 0, - Pending, - Navigation - }; - - struct CaptainModeTarget { - CaptainModeTarget() - : m_target(nullptr), m_function(nullptr) - { - } - - CaptainModeTarget(const QString &p_name, - const QString &p_key, - void *p_target, - CaptainFunc p_func) - : m_name(p_name), - m_key(p_key), - m_target(p_target), - m_function(p_func) - { - } - - QString toString() const - { - return QString("Captain mode target %1 key[%2]").arg(m_name).arg(m_key); - } - - // Name to display. - QString m_name; - - // Key sequence to trigger this target. - // This is the sub-sequence after leader key. - QString m_key; - - // Target. - void *m_target; - - // Function to call when this target is trigger. - CaptainFunc m_function; - }; - - // Restore the focus to m_widgetBeforeCaptain. - void restoreFocus(); - - // Return true if finish handling the event; otherwise, let the base widget - // to handle it. - bool handleKeyPress(int p_key, Qt::KeyboardModifiers p_modifiers); - - // Handle key press event in Navigation mode. - bool handleKeyPressNavigationMode(int p_key, - Qt::KeyboardModifiers p_modifiers); - - // Handle key press event in Captain mode. - bool handleKeyPressCaptainMode(int p_key, - Qt::KeyboardModifiers p_modifiers); - - // Get next major key to use for Navigation mode. - QChar getNextMajorKey(); - - // Trigger navigation mode to ask all targets show themselves. - void triggerNavigationMode(); - - // Exit navigation mode to ask all targets hide themselves. - void exitNavigationMode(); - - void exitCaptainMode(); - - // Called to trigger the action of a Captain target which has - // registered @p_key. - void triggerCaptainTarget(const QString &p_key); - - void setMode(CaptainMode p_mode); - - bool checkMode(CaptainMode p_mode) const; - - void trigger(); - - void triggerCaptainMode(); - - static bool navigationModeByCaptain(void *p_target, void *p_data); - - // Used to indicate current mode. - CaptainMode m_mode; - - // The widget which has the focus before entering Captain mode. - QWidget *m_widgetBeforeCaptain; - - // Targets for Navigation mode. - QVector m_naviTargets; - - QChar m_nextMajorKey; - - // Targets for Captain mode. - // Key(lower) -> CaptainModeTarget. - QHash m_captainTargets; - - // Ignore focus change during handling Captain and Navigation target actions. - bool m_ignoreFocusChange; -}; - -inline void VCaptain::setMode(CaptainMode p_mode) -{ - m_mode = p_mode; -} - -inline bool VCaptain::checkMode(CaptainMode p_mode) const -{ - return m_mode == p_mode; -} - -#endif // VCAPTAIN_H diff --git a/src/vcodeblockhighlighthelper.cpp b/src/vcodeblockhighlighthelper.cpp deleted file mode 100644 index a31f509c..00000000 --- a/src/vcodeblockhighlighthelper.cpp +++ /dev/null @@ -1,292 +0,0 @@ -#include "vcodeblockhighlighthelper.h" - -#include -#include -#include "vdocument.h" -#include "utils/vutils.h" - -VCodeBlockHighlightHelper::VCodeBlockHighlightHelper(HGMarkdownHighlighter *p_highlighter, - VDocument *p_vdoc, - MarkdownConverterType p_type) - : QObject(p_highlighter), - m_highlighter(p_highlighter), - m_vdocument(p_vdoc), - m_type(p_type), - m_timeStamp(0) -{ - connect(m_highlighter, &HGMarkdownHighlighter::codeBlocksUpdated, - this, &VCodeBlockHighlightHelper::handleCodeBlocksUpdated); - connect(m_vdocument, &VDocument::textHighlighted, - this, &VCodeBlockHighlightHelper::handleTextHighlightResult); - - // Web side is ready for code block highlight. - connect(m_vdocument, &VDocument::readyToHighlightText, - m_highlighter, &HGMarkdownHighlighter::updateHighlight); -} - -QString VCodeBlockHighlightHelper::unindentCodeBlock(const QString &p_text) -{ - if (p_text.isEmpty()) { - return p_text; - } - - QStringList lines = p_text.split('\n'); - V_ASSERT(lines[0].trimmed().startsWith("```")); - V_ASSERT(lines.size() > 1); - - QRegExp regExp("(^\\s*)"); - regExp.indexIn(lines[0]); - V_ASSERT(regExp.captureCount() == 1); - int nrSpaces = regExp.capturedTexts()[1].size(); - - if (nrSpaces == 0) { - return p_text; - } - - QString res = lines[0].right(lines[0].size() - nrSpaces); - for (int i = 1; i < lines.size(); ++i) { - const QString &line = lines[i]; - - int idx = 0; - while (idx < nrSpaces && idx < line.size() && line[idx].isSpace()) { - ++idx; - } - res = res + "\n" + line.right(line.size() - idx); - } - - return res; -} - -void VCodeBlockHighlightHelper::handleCodeBlocksUpdated(const QVector &p_codeBlocks) -{ - if (!m_vdocument->isReadyToHighlight()) { - // Immediately return empty results. - QVector emptyRes; - for (int i = 0; i < p_codeBlocks.size(); ++i) { - updateHighlightResults(0, emptyRes); - } - - return; - } - - int curStamp = m_timeStamp.fetchAndAddRelaxed(1) + 1; - m_codeBlocks = p_codeBlocks; - for (int i = 0; i < m_codeBlocks.size(); ++i) { - const VCodeBlock &block = m_codeBlocks[i]; - auto it = m_cache.find(block.m_text); - if (it != m_cache.end()) { - // Hit cache. - qDebug() << "code block highlight hit cache" << curStamp << i; - it.value().m_timeStamp = curStamp; - updateHighlightResults(block.m_startPos, it.value().m_units); - } else { - QString unindentedText = unindentCodeBlock(block.m_text); - m_vdocument->highlightTextAsync(unindentedText, i, curStamp); - } - } -} - -void VCodeBlockHighlightHelper::handleTextHighlightResult(const QString &p_html, - int p_id, - int p_timeStamp) -{ - int curStamp = m_timeStamp.load(); - // Abandon obsolete result. - if (curStamp != p_timeStamp) { - return; - } - parseHighlightResult(p_timeStamp, p_id, p_html); -} - -static void revertEscapedHtml(QString &p_html) -{ - p_html.replace(">", ">").replace("<", "<").replace("&", "&"); -} - -// Search @p_tokenStr in @p_text from p_index. Spaces after `\n` will not make -// a difference in the match. The matched range will be returned as -// [@p_start, @p_end]. Update @p_index to @p_end + 1. -// Set @p_start and @p_end to -1 to indicate mismatch. -static void matchTokenRelaxed(const QString &p_text, const QString &p_tokenStr, - int &p_index, int &p_start, int &p_end) -{ - QString regStr = QRegExp::escape(p_tokenStr); - // Do not replace the ending '\n'. - regStr.replace(QRegExp("\n(?!$)"), "\\s+"); - QRegExp regExp(regStr); - p_start = p_text.indexOf(regExp, p_index); - if (p_start == -1) { - p_end = -1; - return; - } - - p_end = p_start + regExp.matchedLength() - 1; - p_index = p_end + 1; -} - -// For now, we could only handle code blocks outside the list. -void VCodeBlockHighlightHelper::parseHighlightResult(int p_timeStamp, - int p_idx, - const QString &p_html) -{ - const VCodeBlock &block = m_codeBlocks.at(p_idx); - int startPos = block.m_startPos; - QString text = block.m_text; - - QVector hlUnits; - - bool failed = true; - - QXmlStreamReader xml(p_html); - - // Must have a fenced line at the front. - // textIndex is the start index in the code block text to search for. - int textIndex = text.indexOf('\n'); - if (textIndex == -1) { - goto exit; - } - ++textIndex; - - if (xml.readNextStartElement()) { - if (xml.name() != "pre") { - goto exit; - } - - if (!xml.readNextStartElement()) { - goto exit; - } - - if (xml.name() != "code") { - goto exit; - } - - while (xml.readNext()) { - if (xml.isCharacters()) { - // Revert the HTML escape to match. - QString tokenStr = xml.text().toString(); - revertEscapedHtml(tokenStr); - - int start, end; - matchTokenRelaxed(text, tokenStr, textIndex, start, end); - if (start == -1) { - failed = true; - goto exit; - } - } else if (xml.isStartElement()) { - if (xml.name() != "span") { - failed = true; - goto exit; - } - if (!parseSpanElement(xml, text, textIndex, hlUnits)) { - failed = true; - goto exit; - } - } else if (xml.isEndElement()) { - if (xml.name() != "code" && xml.name() != "pre") { - failed = true; - } else { - failed = false; - } - goto exit; - } else { - failed = true; - goto exit; - } - } - } - -exit: - // Pass result back to highlighter. - int curStamp = m_timeStamp.load(); - // Abandon obsolete result. - if (curStamp != p_timeStamp) { - return; - } - - if (xml.hasError() || failed) { - qWarning() << "fail to parse highlighted result" - << "stamp:" << p_timeStamp << "index:" << p_idx << p_html; - hlUnits.clear(); - } - - // Add it to cache. - addToHighlightCache(text, p_timeStamp, hlUnits); - - updateHighlightResults(startPos, hlUnits); -} - -void VCodeBlockHighlightHelper::updateHighlightResults(int p_startPos, - QVector p_units) -{ - for (int i = 0; i < p_units.size(); ++i) { - p_units[i].m_position += p_startPos; - } - - // We need to call this function anyway to trigger the rehighlight. - m_highlighter->setCodeBlockHighlights(p_units); -} - -bool VCodeBlockHighlightHelper::parseSpanElement(QXmlStreamReader &p_xml, - const QString &p_text, - int &p_index, - QVector &p_units) -{ - int unitStart = p_index; - QString style = p_xml.attributes().value("class").toString(); - - while (p_xml.readNext()) { - if (p_xml.isCharacters()) { - // Revert the HTML escape to match. - QString tokenStr = p_xml.text().toString(); - revertEscapedHtml(tokenStr); - - int start, end; - matchTokenRelaxed(p_text, tokenStr, p_index, start, end); - if (start == -1) { - return false; - } - } else if (p_xml.isStartElement()) { - if (p_xml.name() != "span") { - return false; - } - - // Sub-span. - if (!parseSpanElement(p_xml, p_text, p_index, p_units)) { - return false; - } - } else if (p_xml.isEndElement()) { - if (p_xml.name() != "span") { - return false; - } - - // Got a complete span. Use relative position here. - HLUnitPos unit(unitStart, p_index - unitStart, style); - p_units.append(unit); - return true; - } else { - return false; - } - } - return false; -} - -void VCodeBlockHighlightHelper::addToHighlightCache(const QString &p_text, - int p_timeStamp, - const QVector &p_units) -{ - const int c_maxEntries = 100; - const int c_maxTimeStampSpan = 3; - if (m_cache.size() >= c_maxEntries) { - // Remove the oldest one. - int ts = p_timeStamp - c_maxTimeStampSpan; - for (auto it = m_cache.begin(); it != m_cache.end();) { - if (it.value().m_timeStamp < ts) { - it = m_cache.erase(it); - } else { - ++it; - } - } - } - - m_cache.insert(p_text, HLResult(p_timeStamp, p_units)); -} diff --git a/src/vcodeblockhighlighthelper.h b/src/vcodeblockhighlighthelper.h deleted file mode 100644 index 0f194c56..00000000 --- a/src/vcodeblockhighlighthelper.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef VCODEBLOCKHIGHLIGHTHELPER_H -#define VCODEBLOCKHIGHLIGHTHELPER_H - -#include -#include -#include -#include -#include -#include "vconfigmanager.h" - -class VDocument; - -class VCodeBlockHighlightHelper : public QObject -{ - Q_OBJECT -public: - VCodeBlockHighlightHelper(HGMarkdownHighlighter *p_highlighter, - VDocument *p_vdoc, MarkdownConverterType p_type); - -private slots: - void handleCodeBlocksUpdated(const QVector &p_codeBlocks); - - void handleTextHighlightResult(const QString &p_html, int p_id, int p_timeStamp); - -private: - struct HLResult - { - HLResult() : m_timeStamp(-1) - { - } - - HLResult(int p_timeStamp, const QVector &p_units) - : m_timeStamp(p_timeStamp), m_units(p_units) - { - } - - int m_timeStamp; - QVector m_units; - }; - - void parseHighlightResult(int p_timeStamp, int p_idx, const QString &p_html); - - // @p_text: the raw text of the code block; - // @p_index: the start index of the span element within @p_text; - // @p_units: all the highlight units of this code block; - bool parseSpanElement(QXmlStreamReader &p_xml, - const QString &p_text, int &p_index, - QVector &p_units); - - // @p_text: text of fenced code block. - // Get the indent level of the first line (fence) and unindent the whole block - // to make the fence at the highest indent level. - // This operation is to make sure JS could handle the code block correctly - // without any context. - QString unindentCodeBlock(const QString &p_text); - - void updateHighlightResults(int p_startPos, QVector p_units); - - void addToHighlightCache(const QString &p_text, - int p_timeStamp, - const QVector &p_units); - - HGMarkdownHighlighter *m_highlighter; - VDocument *m_vdocument; - MarkdownConverterType m_type; - QAtomicInteger m_timeStamp; - QVector m_codeBlocks; - - // Cache for highlight result, using the code block text as key. - // The HLResult has relative position only. - QHash m_cache; -}; - -#endif // VCODEBLOCKHIGHLIGHTHELPER_H diff --git a/src/vconfigmanager.cpp b/src/vconfigmanager.cpp deleted file mode 100644 index b59f83ab..00000000 --- a/src/vconfigmanager.cpp +++ /dev/null @@ -1,1272 +0,0 @@ -#include "vconfigmanager.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "utils/vutils.h" -#include "vstyleparser.h" -#include "vpalette.h" - -const QString VConfigManager::orgName = QString("vnote"); - -const QString VConfigManager::appName = QString("vnote"); - -const QString VConfigManager::c_version = QString("1.11"); - -const QString VConfigManager::c_obsoleteDirConfigFile = QString(".vnote.json"); - -const QString VConfigManager::c_dirConfigFile = QString("_vnote.json"); - -const QString VConfigManager::c_defaultConfigFilePath = QString(":/resources/vnote.ini"); - -const QString VConfigManager::c_defaultConfigFile = QString("vnote.ini"); - -const QString VConfigManager::c_sessionConfigFile = QString("session.ini"); - -const QString VConfigManager::c_snippetConfigFile = QString("snippet.json"); - -const QString VConfigManager::c_styleConfigFolder = QString("styles"); - -const QString VConfigManager::c_themeConfigFolder = QString("themes"); - -const QString VConfigManager::c_codeBlockStyleConfigFolder = QString("codeblock_styles"); - -const QString VConfigManager::c_templateConfigFolder = QString("templates"); - -const QString VConfigManager::c_snippetConfigFolder = QString("snippets"); - -const QString VConfigManager::c_warningTextStyle = QString("color: #C9302C; font: bold"); - -const QString VConfigManager::c_dataTextStyle = QString("font: bold"); - -const QString VConfigManager::c_vnoteNotebookFolderName = QString("vnote_notebooks"); - -VConfigManager::VConfigManager(QObject *p_parent) - : QObject(p_parent), - userSettings(NULL), - defaultSettings(NULL), - m_sessionSettings(NULL) -{ -} - -void VConfigManager::initialize() -{ - initSettings(); - - initThemes(); - - initEditorStyles(); - - initCssStyles(); - - initCodeBlockCssStyles(); - - m_theme = getConfigFromSettings("global", "theme").toString(); - - m_editorStyle = getConfigFromSettings("global", "editor_style").toString(); - - m_cssStyle = getConfigFromSettings("global", "css_style").toString(); - - m_codeBlockCssStyle = getConfigFromSettings("global", "code_block_css_style").toString(); - - m_defaultEditPalette = QTextEdit().palette(); - - welcomePagePath = getConfigFromSettings("global", "welcome_page_path").toString(); - - markdownExtensions = hoedown_extensions(HOEDOWN_EXT_TABLES | HOEDOWN_EXT_FENCED_CODE | - HOEDOWN_EXT_HIGHLIGHT | HOEDOWN_EXT_AUTOLINK | - HOEDOWN_EXT_QUOTE | HOEDOWN_EXT_MATH | HOEDOWN_EXT_MATH_EXPLICIT); - mdConverterType = (MarkdownConverterType)getConfigFromSettings("global", "markdown_converter").toInt(); - - tabStopWidth = getConfigFromSettings("global", "tab_stop_width").toInt(); - isExpandTab = getConfigFromSettings("global", "is_expand_tab").toBool(); - m_highlightCursorLine = getConfigFromSettings("global", "highlight_cursor_line").toBool(); - m_highlightSelectedWord = getConfigFromSettings("global", "highlight_selected_word").toBool(); - m_highlightSearchedWord = getConfigFromSettings("global", "highlight_searched_word").toBool(); - m_autoIndent = getConfigFromSettings("global", "auto_indent").toBool(); - m_autoList = getConfigFromSettings("global", "auto_list").toBool(); - - readPredefinedColorsFromSettings(); - curBackgroundColor = getConfigFromSettings("global", "current_background_color").toString(); - - updateEditStyle(); - - curRenderBackgroundColor = getConfigFromSettings("global", - "current_render_background_color").toString(); - - m_toolsDockChecked = getConfigFromSettings("global", "tools_dock_checked").toBool(); - - m_findCaseSensitive = getConfigFromSettings("global", - "find_case_sensitive").toBool(); - m_findWholeWordOnly = getConfigFromSettings("global", - "find_whole_word_only").toBool(); - m_findRegularExpression = getConfigFromSettings("global", - "find_regular_expression").toBool(); - m_findIncrementalSearch = getConfigFromSettings("global", - "find_incremental_search").toBool(); - - m_language = getConfigFromSettings("global", "language").toString(); - - m_enableMermaid = getConfigFromSettings("global", "enable_mermaid").toBool(); - - m_enableFlowchart = getConfigFromSettings("global", "enable_flowchart").toBool(); - - m_enableMathjax = getConfigFromSettings("global", "enable_mathjax").toBool(); - - m_webZoomFactor = getConfigFromSettings("global", "web_zoom_factor").toReal(); - if (!isCustomWebZoomFactor()) { - // Calculate the zoom factor based on DPI. - m_webZoomFactor = VUtils::calculateScaleFactor(); - qDebug() << "set WebZoomFactor to" << m_webZoomFactor; - } - - m_enableCodeBlockHighlight = getConfigFromSettings("global", - "enable_code_block_highlight").toBool(); - - m_enablePreviewImages = getConfigFromSettings("global", - "enable_preview_images").toBool(); - - m_enablePreviewImageConstraint = getConfigFromSettings("global", - "enable_preview_image_constraint").toBool(); - - m_enableImageConstraint = getConfigFromSettings("global", - "enable_image_constraint").toBool(); - - m_enableImageCaption = getConfigFromSettings("global", - "enable_image_caption").toBool(); - - m_imageFolder = getConfigFromSettings("global", - "image_folder").toString(); - - m_imageFolderExt = getConfigFromSettings("global", - "external_image_folder").toString(); - - m_attachmentFolder = getConfigFromSettings("global", - "attachment_folder").toString(); - if (m_attachmentFolder.isEmpty()) { - // Reset the default folder. - m_attachmentFolder = resetDefaultConfig("global", "attachment_folder").toString(); - } - - m_enableTrailingSpaceHighlight = getConfigFromSettings("global", - "enable_trailing_space_highlight").toBool(); - - m_enableVimMode = getConfigFromSettings("global", - "enable_vim_mode").toBool(); - - m_enableSmartImInVimMode = getConfigFromSettings("global", - "enable_smart_im_in_vim_mode").toBool(); - - m_editorLineNumber = getConfigFromSettings("global", - "editor_line_number").toInt(); - - m_minimizeToSystemTray = getConfigFromSettings("global", - "minimize_to_system_tray").toInt(); - if (m_minimizeToSystemTray > 1 || m_minimizeToSystemTray < -1) { - setMinimizeToSystemTray(0); - } - - readShortcutsFromSettings(); - - readCaptainShortcutsFromSettings(); - - initDocSuffixes(); - - m_markdownHighlightInterval = getConfigFromSettings("global", - "markdown_highlight_interval").toInt(); - - m_lineDistanceHeight = getConfigFromSettings("global", - "line_distance_height").toInt(); - - m_insertTitleFromNoteName = getConfigFromSettings("global", - "insert_title_from_note_name").toBool(); - - int openMode = getConfigFromSettings("global", - "note_open_mode").toInt(); - if (openMode == 1) { - m_noteOpenMode = OpenFileMode::Edit; - } else { - m_noteOpenMode = OpenFileMode::Read; - } - - int tmpHeadingSequenceType = getConfigFromSettings("global", - "heading_sequence_type").toInt(); - if (tmpHeadingSequenceType < (int)HeadingSequenceType::Invalid - && tmpHeadingSequenceType >= (int)HeadingSequenceType::Disabled) { - m_headingSequenceType = (HeadingSequenceType)tmpHeadingSequenceType; - } else { - m_headingSequenceType = HeadingSequenceType::Disabled; - } - - m_headingSequenceBaseLevel = getConfigFromSettings("global", - "heading_sequence_base_level").toInt(); - - m_colorColumn = getConfigFromSettings("global", "color_column").toInt(); - - m_enableCodeBlockLineNumber = getConfigFromSettings("global", - "enable_code_block_line_number").toBool(); - - m_toolBarIconSize = getConfigFromSettings("global", - "tool_bar_icon_size").toInt(); - - m_markdownitOptHtml = getConfigFromSettings("global", - "markdownit_opt_html").toBool(); - - m_markdownitOptBreaks = getConfigFromSettings("global", - "markdownit_opt_breaks").toBool(); - - m_markdownitOptLinkify = getConfigFromSettings("global", - "markdownit_opt_linkify").toBool(); - - m_recycleBinFolder = getConfigFromSettings("global", - "recycle_bin_folder").toString(); - - m_recycleBinFolderExt = getConfigFromSettings("global", - "external_recycle_bin_folder").toString(); - - m_confirmImagesCleanUp = getConfigFromSettings("global", - "confirm_images_clean_up").toBool(); - - m_confirmReloadFolder = getConfigFromSettings("global", - "confirm_reload_folder").toBool(); - - m_mathjaxJavascript = getConfigFromSettings("web", - "mathjax_javascript").toString(); - - m_doubleClickCloseTab = getConfigFromSettings("global", - "double_click_close_tab").toBool(); - - m_enableCompactMode = getConfigFromSettings("global", - "enable_compact_mode").toBool(); - - int tmpStartupPageMode = getConfigFromSettings("global", - "startup_page_type").toInt(); - if (tmpStartupPageMode < (int)StartupPageType::Invalid - && tmpStartupPageMode >= (int)StartupPageType::None) { - m_startupPageType = (StartupPageType)tmpStartupPageMode; - } else { - m_startupPageType = StartupPageType::None; - } - - m_startupPages = getConfigFromSettings("global", - "startup_pages").toStringList(); - - initFromSessionSettings(); - - m_fileTimerInterval = getConfigFromSettings("global", - "file_timer_interval").toInt(); - if (m_fileTimerInterval < 100) { - m_fileTimerInterval = 100; - } - - m_backupDirectory = getConfigFromSettings("global", - "backup_directory").toString(); - - m_backupExtension = getConfigFromSettings("global", - "backup_extension").toString(); - if (m_backupExtension.isEmpty()) { - m_backupExtension = "."; - } - - m_enableBackupFile = getConfigFromSettings("global", - "enable_backup_file").toBool(); - - m_vimExemptionKeys = getConfigFromSettings("global", - "vim_exemption_keys").toString(); -} - -void VConfigManager::initSettings() -{ - Q_ASSERT(!userSettings && !defaultSettings && !m_sessionSettings); - - const char *codecForIni = "UTF-8"; - - // vnote.ini. - // First try to read vnote.ini from the directory of the executable. - QString userIniPath = QDir(QCoreApplication::applicationDirPath()).filePath(c_defaultConfigFile); - if (QFileInfo::exists(userIniPath)) { - userSettings = new QSettings(userIniPath, - QSettings::IniFormat, - this); - } else { - userSettings = new QSettings(QSettings::IniFormat, - QSettings::UserScope, - orgName, - appName, - this); - } - - userSettings->setIniCodec(codecForIni); - - qDebug() << "use user config" << userSettings->fileName(); - - // Default vnote.ini from resource file. - defaultSettings = new QSettings(c_defaultConfigFilePath, QSettings::IniFormat, this); - defaultSettings->setIniCodec(codecForIni); - - // session.ini. - m_sessionSettings = new QSettings(QDir(getConfigFolder()).filePath(c_sessionConfigFile), - QSettings::IniFormat, - this); - m_sessionSettings->setIniCodec(codecForIni); -} - -void VConfigManager::initFromSessionSettings() -{ - curNotebookIndex = getConfigFromSessionSettings("global", "current_notebook").toInt(); - - m_mainWindowGeometry = getConfigFromSessionSettings("geometry", - "main_window_geometry").toByteArray(); - - m_mainWindowState = getConfigFromSessionSettings("geometry", - "main_window_state").toByteArray(); - - m_mainSplitterState = getConfigFromSessionSettings("geometry", - "main_splitter_state").toByteArray(); - - m_naviSplitterState = getConfigFromSessionSettings("geometry", - "navi_splitter_state").toByteArray(); -} - -void VConfigManager::readPredefinedColorsFromSettings() -{ - predefinedColors.clear(); - int size = defaultSettings->beginReadArray("predefined_colors"); - for (int i = 0; i < size; ++i) { - defaultSettings->setArrayIndex(i); - VColor color; - color.name = defaultSettings->value("name").toString(); - color.rgb = defaultSettings->value("rgb").toString(); - predefinedColors.append(color); - } - defaultSettings->endArray(); - qDebug() << "read" << predefinedColors.size() - << "pre-defined colors from [predefined_colors] section"; -} - -void VConfigManager::readNotebookFromSettings(QSettings *p_settings, - QVector &p_notebooks, - QObject *parent) -{ - Q_ASSERT(p_notebooks.isEmpty()); - int size = p_settings->beginReadArray("notebooks"); - for (int i = 0; i < size; ++i) { - p_settings->setArrayIndex(i); - QString name = p_settings->value("name").toString(); - QString path = p_settings->value("path").toString(); - VNotebook *notebook = new VNotebook(name, path, parent); - notebook->readConfigNotebook(); - p_notebooks.append(notebook); - } - - p_settings->endArray(); - qDebug() << "read" << p_notebooks.size() - << "notebook items from [notebooks] section"; -} - -void VConfigManager::writeNotebookToSettings(QSettings *p_settings, - const QVector &p_notebooks) -{ - // Clear it first - p_settings->beginGroup("notebooks"); - p_settings->remove(""); - p_settings->endGroup(); - - p_settings->beginWriteArray("notebooks"); - for (int i = 0; i < p_notebooks.size(); ++i) { - p_settings->setArrayIndex(i); - const VNotebook ¬ebook = *p_notebooks[i]; - p_settings->setValue("name", notebook.getName()); - p_settings->setValue("path", notebook.getPath()); - } - - p_settings->endArray(); - qDebug() << "write" << p_notebooks.size() - << "notebook items in [notebooks] section"; -} - -static QVariant getConfigFromSettingsBySectionKey(const QSettings *p_settings, - const QString &p_section, - const QString &p_key) -{ - QString fullKey = p_section + "/" + p_key; - return p_settings->value(fullKey); -} - -static void setConfigToSettingsBySectionKey(QSettings *p_settings, - const QString &p_section, - const QString &p_key, - const QVariant &p_value) -{ - QString fullKey = p_section + "/" + p_key; - return p_settings->setValue(fullKey, p_value); -} - -QVariant VConfigManager::getConfigFromSettings(const QString §ion, const QString &key) const -{ - // First, look up the user-scoped config file - QVariant value = getConfigFromSettingsBySectionKey(userSettings, section, key); - if (!value.isNull()) { - qDebug() << "user config:" << (section + "/" + key) << value; - return value; - } - - // Second, look up the default config file - return getDefaultConfig(section, key); -} - -void VConfigManager::setConfigToSettings(const QString §ion, const QString &key, const QVariant &value) -{ - // Set the user-scoped config file - setConfigToSettingsBySectionKey(userSettings, section, key, value); - qDebug() << "set user config:" << (section + "/" + key) << value; -} - -QVariant VConfigManager::getDefaultConfig(const QString &p_section, const QString &p_key) const -{ - QVariant value = getConfigFromSettingsBySectionKey(defaultSettings, p_section, p_key); - qDebug() << "default config:" << (p_section + "/" + p_key) << value; - return value; -} - -QVariant VConfigManager::resetDefaultConfig(const QString &p_section, const QString &p_key) -{ - QVariant defaultValue = getDefaultConfig(p_section, p_key); - setConfigToSettings(p_section, p_key, defaultValue); - - return defaultValue; -} - -QVariant VConfigManager::getConfigFromSessionSettings(const QString &p_section, - const QString &p_key) const -{ - return getConfigFromSettingsBySectionKey(m_sessionSettings, - p_section, - p_key); -} - -void VConfigManager::setConfigToSessionSettings(const QString &p_section, - const QString &p_key, - const QVariant &p_value) -{ - setConfigToSettingsBySectionKey(m_sessionSettings, - p_section, - p_key, - p_value); -} - -QString VConfigManager::fetchDirConfigFilePath(const QString &p_path) -{ - QDir dir(p_path); - QString fileName = c_dirConfigFile; - - if (dir.exists(c_obsoleteDirConfigFile)) { - V_ASSERT(!dir.exists(c_dirConfigFile)); - if (!dir.rename(c_obsoleteDirConfigFile, c_dirConfigFile)) { - fileName = c_obsoleteDirConfigFile; - } - qDebug() << "rename old directory config file:" << fileName; - } - - QString filePath = QDir::cleanPath(dir.filePath(fileName)); - qDebug() << "use directory config file:" << filePath; - return filePath; -} - -QJsonObject VConfigManager::readDirectoryConfig(const QString &path) -{ - QString configFile = fetchDirConfigFilePath(path); - - QFile config(configFile); - if (!config.open(QIODevice::ReadOnly)) { - qWarning() << "fail to read directory configuration file:" - << configFile; - return QJsonObject(); - } - - QByteArray configData = config.readAll(); - return QJsonDocument::fromJson(configData).object(); -} - -bool VConfigManager::directoryConfigExist(const QString &path) -{ - return QFileInfo::exists(fetchDirConfigFilePath(path)); -} - -bool VConfigManager::writeDirectoryConfig(const QString &path, const QJsonObject &configJson) -{ - QString configFile = fetchDirConfigFilePath(path); - - QFile config(configFile); - // We use Unix LF for config file. - if (!config.open(QIODevice::WriteOnly)) { - qWarning() << "fail to open directory configuration file for write:" - << configFile; - return false; - } - - QJsonDocument configDoc(configJson); - config.write(configDoc.toJson()); - return true; -} - -bool VConfigManager::deleteDirectoryConfig(const QString &path) -{ - QString configFile = fetchDirConfigFilePath(path); - - QFile config(configFile); - if (!config.remove()) { - qWarning() << "fail to delete directory configuration file:" - << configFile; - return false; - } - - qDebug() << "delete config file:" << configFile; - return true; -} - -QString VConfigManager::getLogFilePath() const -{ - return QDir(getConfigFolder()).filePath("vnote.log"); -} - -void VConfigManager::updateMarkdownEditStyle() -{ - static const QString defaultCurrentLineBackground = "#C5CAE9"; - - static const QString defaultVimNormalBg = "#BCBCBC"; - static const QString defaultVimInsertBg = "#C5CAE9"; - static const QString defaultVimVisualBg = "#90CAF9"; - static const QString defaultVimReplaceBg = "#F8BBD0"; - - static const QString defaultTrailingSpaceBg = "#A8A8A8"; - static const QString defaultSelectedWordBg = "#DFDF00"; - static const QString defaultSearchedWordBg = "#81C784"; - static const QString defaultSearchedWordCursorBg = "#4DB6AC"; - static const QString defaultIncrementalSearchedWordBg = "#CE93D8"; - static const QString defaultLineNumberBg = "#BDBDBD"; - static const QString defaultLineNumberFg = "#424242"; - static const QString defaultColorColumnBg = "#DD0000"; - static const QString defaultColorColumnFg = "#FFFF00"; - static const QString defaultPreviewImageLineFg = "#9575CD"; - - // Read style file .mdhl - QString file(getEditorStyleFile()); - - qDebug() << "use editor style file" << file; - - QString styleStr = VUtils::readFileFromDisk(file); - if (styleStr.isEmpty()) { - return; - } - - mdEditPalette = baseEditPalette; - mdEditFont = baseEditFont; - - VStyleParser parser; - parser.parseMarkdownStyle(styleStr); - - QMap> styles; - parser.fetchMarkdownEditorStyles(mdEditPalette, mdEditFont, styles); - - mdHighlightingStyles = parser.fetchMarkdownStyles(mdEditFont); - m_codeBlockStyles = parser.fetchCodeBlockStyles(mdEditFont); - - m_editorCurrentLineBg = defaultCurrentLineBackground; - m_editorVimInsertBg = defaultVimInsertBg; - m_editorVimNormalBg = defaultVimNormalBg; - m_editorVimVisualBg = defaultVimVisualBg; - m_editorVimReplaceBg = defaultVimReplaceBg; - - auto editorCurrentLineIt = styles.find("editor-current-line"); - if (editorCurrentLineIt != styles.end()) { - auto backgroundIt = editorCurrentLineIt->find("background"); - if (backgroundIt != editorCurrentLineIt->end()) { - // Do not need to add "#" here, since this is a built-in attribute. - m_editorCurrentLineBg = *backgroundIt; - } - - auto vimBgIt = editorCurrentLineIt->find("vim-insert-background"); - if (vimBgIt != editorCurrentLineIt->end()) { - m_editorVimInsertBg = "#" + *vimBgIt; - } - - vimBgIt = editorCurrentLineIt->find("vim-normal-background"); - if (vimBgIt != editorCurrentLineIt->end()) { - m_editorVimNormalBg = "#" + *vimBgIt; - } - - vimBgIt = editorCurrentLineIt->find("vim-visual-background"); - if (vimBgIt != editorCurrentLineIt->end()) { - m_editorVimVisualBg = "#" + *vimBgIt; - } - - vimBgIt = editorCurrentLineIt->find("vim-replace-background"); - if (vimBgIt != editorCurrentLineIt->end()) { - m_editorVimReplaceBg = "#" + *vimBgIt; - } - } - - m_editorTrailingSpaceBg = defaultTrailingSpaceBg; - m_editorSelectedWordBg = defaultSelectedWordBg; - m_editorSearchedWordBg = defaultSearchedWordBg; - m_editorSearchedWordCursorBg = defaultSearchedWordCursorBg; - m_editorIncrementalSearchedWordBg = defaultIncrementalSearchedWordBg; - m_editorLineNumberBg = defaultLineNumberBg; - m_editorLineNumberFg = defaultLineNumberFg; - m_editorColorColumnBg = defaultColorColumnBg; - m_editorColorColumnFg = defaultColorColumnFg; - m_editorPreviewImageLineFg = defaultPreviewImageLineFg; - auto editorIt = styles.find("editor"); - if (editorIt != styles.end()) { - auto it = editorIt->find("trailing-space"); - if (it != editorIt->end()) { - m_editorTrailingSpaceBg = "#" + *it; - } - - it = editorIt->find("line-number-background"); - if (it != editorIt->end()) { - m_editorLineNumberBg = "#" + *it; - } - - it = editorIt->find("line-number-foreground"); - if (it != editorIt->end()) { - m_editorLineNumberFg = "#" + *it; - } - - it = editorIt->find("selected-word-background"); - if (it != editorIt->end()) { - m_editorSelectedWordBg = "#" + *it; - } - - it = editorIt->find("searched-word-background"); - if (it != editorIt->end()) { - m_editorSearchedWordBg = "#" + *it; - } - - it = editorIt->find("searched-word-cursor-background"); - if (it != editorIt->end()) { - m_editorSearchedWordCursorBg = "#" + *it; - } - - it = editorIt->find("incremental-searched-word-background"); - if (it != editorIt->end()) { - m_editorIncrementalSearchedWordBg = "#" + *it; - } - - it = editorIt->find("color-column-background"); - if (it != editorIt->end()) { - m_editorColorColumnBg = "#" + *it; - } - - it = editorIt->find("color-column-foreground"); - if (it != editorIt->end()) { - m_editorColorColumnFg = "#" + *it; - } - - it = editorIt->find("preview-image-line-foreground"); - if (it != editorIt->end()) { - m_editorPreviewImageLineFg = "#" + *it; - } - } -} - -void VConfigManager::updateEditStyle() -{ - // Reset font and palette. - baseEditFont = mdEditFont = m_defaultEditFont; - baseEditPalette = mdEditPalette = m_defaultEditPalette; - - static const QColor defaultColor = m_defaultEditPalette.color(QPalette::Base); - QColor newColor = defaultColor; - bool force = false; - if (curBackgroundColor != "System") { - for (int i = 0; i < predefinedColors.size(); ++i) { - if (predefinedColors[i].name == curBackgroundColor) { - QString rgb = predefinedColors[i].rgb; - if (!rgb.isEmpty()) { - newColor = QColor(VUtils::QRgbFromString(rgb)); - force = true; - } - - break; - } - } - } - - baseEditPalette.setColor(QPalette::Base, newColor); - - // Update markdown editor palette - updateMarkdownEditStyle(); - - // Base editor will use the same font size as the markdown editor by now. - if (mdEditFont.pointSize() > -1) { - baseEditFont.setPointSize(mdEditFont.pointSize()); - } - - if (force) { - mdEditPalette.setColor(QPalette::Base, newColor); - } -} - -void VConfigManager::setWebZoomFactor(qreal p_factor) -{ - if (isCustomWebZoomFactor()) { - if (VUtils::realEqual(m_webZoomFactor, p_factor)) { - return; - } else if (VUtils::realEqual(p_factor, -1)) { - m_webZoomFactor = VUtils::calculateScaleFactor(); - setConfigToSettings("global", "web_zoom_factor", -1); - return; - } - } else { - if (VUtils::realEqual(p_factor, -1)) { - return; - } - } - m_webZoomFactor = p_factor; - setConfigToSettings("global", "web_zoom_factor", m_webZoomFactor); -} - -QString VConfigManager::getConfigFolder() const -{ - V_ASSERT(userSettings); - - QString iniPath = userSettings->fileName(); - return VUtils::basePathFromPath(iniPath); -} - -QString VConfigManager::getConfigFilePath() const -{ - V_ASSERT(userSettings); - - return userSettings->fileName(); -} - -const QString &VConfigManager::getStyleConfigFolder() const -{ - static QString path = QDir(getConfigFolder()).filePath(c_styleConfigFolder); - return path; -} - -const QString &VConfigManager::getThemeConfigFolder() const -{ - static QString path = QDir(getConfigFolder()).filePath(c_themeConfigFolder); - return path; -} - -const QString &VConfigManager::getCodeBlockStyleConfigFolder() const -{ - static QString path = QDir(getStyleConfigFolder()).filePath(c_codeBlockStyleConfigFolder); - return path; -} - -const QString &VConfigManager::getTemplateConfigFolder() const -{ - static QString path = QDir(getConfigFolder()).filePath(c_templateConfigFolder); - return path; -} - -const QString &VConfigManager::getSnippetConfigFolder() const -{ - static QString path = QDir(getConfigFolder()).filePath(c_snippetConfigFolder); - return path; -} - -const QString &VConfigManager::getSnippetConfigFilePath() const -{ - static QString path = QDir(getSnippetConfigFolder()).filePath(c_snippetConfigFile); - return path; -} - -QString VConfigManager::getThemeFile() const -{ - auto it = m_themes.find(m_theme); - if (it != m_themes.end()) { - return it.value(); - } else { - qWarning() << "use default theme due to missing specified theme" << m_theme; - const_cast(this)->m_theme = getDefaultConfig("global", "theme").toString(); - return m_themes[m_theme]; - } -} - -QVector VConfigManager::getNoteTemplates(DocType p_type) const -{ - QVector res; - QDir dir(getTemplateConfigFolder()); - if (!dir.exists()) { - dir.mkpath(getTemplateConfigFolder()); - return res; - } - - dir.setFilter(QDir::Files | QDir::NoSymLinks); - QStringList files = dir.entryList(); - res.reserve(files.size()); - for (auto const &item : files) { - if (p_type == DocType::Unknown - || p_type == VUtils::docTypeFromName(item)) { - res.push_back(item); - } - } - - return res; -} - -// The URL will be used in the Web page. -QString VConfigManager::getCssStyleUrl() const -{ - Q_ASSERT(!m_themes.isEmpty()); - Q_ASSERT(!m_cssStyles.isEmpty()); - - if (m_cssStyle.isEmpty()) { - // Use theme's style. - const_cast(this)->m_cssStyle = VPalette::themeCssStyle(getThemeFile()); - } - - QString cssPath; - auto it = m_cssStyles.find(m_cssStyle); - if (it != m_cssStyles.end()) { - cssPath = it.value(); - } - - if (cssPath.startsWith(":")) { - cssPath = "qrc" + cssPath; - } else { - QUrl cssUrl = QUrl::fromLocalFile(cssPath); - cssPath = cssUrl.toString(); - } - - qDebug() << "use css style file" << cssPath; - return cssPath; -} - -QString VConfigManager::getCodeBlockCssStyleUrl() const -{ - Q_ASSERT(!m_themes.isEmpty()); - Q_ASSERT(!m_codeBlockCssStyles.isEmpty()); - - if (m_codeBlockCssStyle.isEmpty()) { - // Use theme's style. - const_cast(this)->m_codeBlockCssStyle = - VPalette::themeCodeBlockCssStyle(getThemeFile()); - } - - QString cssPath; - auto it = m_codeBlockCssStyles.find(m_codeBlockCssStyle); - if (it != m_codeBlockCssStyles.end()) { - cssPath = it.value(); - } - - if (cssPath.startsWith(":")) { - cssPath = "qrc" + cssPath; - } else { - QUrl cssUrl = QUrl::fromLocalFile(cssPath); - cssPath = cssUrl.toString(); - } - - qDebug() << "use code block css style file" << cssPath; - return cssPath; -} - -QString VConfigManager::getEditorStyleFile() const -{ - Q_ASSERT(!m_themes.isEmpty()); - Q_ASSERT(!m_editorStyles.isEmpty()); - - if (m_editorStyle.isEmpty()) { - // Use theme's style. - const_cast(this)->m_editorStyle = VPalette::themeEditorStyle(getThemeFile()); - } - - auto it = m_editorStyles.find(m_editorStyle); - if (it != m_editorStyles.end()) { - return it.value(); - } - - return QString(); -} - -QString VConfigManager::getVnoteNotebookFolderPath() -{ - return QDir::home().filePath(c_vnoteNotebookFolderName); -} - -QHash VConfigManager::readShortcutsFromSettings(QSettings *p_settings, - const QString &p_group) -{ - QHash ret; - p_settings->beginGroup(p_group); - QStringList keys = p_settings->childKeys(); - for (auto const & key : keys) { - if (key.isEmpty()) { - continue; - } - - QVariant varVal = p_settings->value(key); - QString sequence = varVal.toString(); - if (varVal.type() == QVariant::StringList) { - sequence = varVal.toStringList().join(","); - } - - sequence = sequence.trimmed(); - if (isValidKeySequence(sequence)) { - ret.insert(key, sequence); - } - } - - p_settings->endGroup(); - - return ret; -} - -bool VConfigManager::isValidKeySequence(const QString &p_seq) -{ - return p_seq.isEmpty() - || (p_seq.toLower() != "ctrl+q" && !QKeySequence(p_seq).isEmpty()); -} - -void VConfigManager::readShortcutsFromSettings() -{ - const QString group("shortcuts"); - - m_shortcuts.clear(); - m_shortcuts = readShortcutsFromSettings(defaultSettings, group); - - // Update default settings according to user settings. - QHash userShortcuts = readShortcutsFromSettings(userSettings, - group); - QSet matched; - matched.reserve(m_shortcuts.size()); - for (auto it = userShortcuts.begin(); it != userShortcuts.end(); ++it) { - auto defaultIt = m_shortcuts.find(it.key()); - if (defaultIt != m_shortcuts.end()) { - QString sequence = it.value().trimmed(); - if (sequence != defaultIt.value()) { - if (isValidKeySequence(sequence)) { - matched.insert(it.key()); - *defaultIt = sequence; - } - } else { - matched.insert(it.key()); - } - } - } - - if (matched.size() < m_shortcuts.size()) { - qDebug() << "override user shortcuts settings using default settings"; - writeShortcutsToSettings(userSettings, group, m_shortcuts); - } -} - -void VConfigManager::readCaptainShortcutsFromSettings() -{ - const QString group("captain_mode_shortcuts"); - - m_captainShortcuts.clear(); - m_captainShortcuts = readShortcutsFromSettings(defaultSettings, group); - - // Update default settings according to user settings. - QHash userShortcuts = readShortcutsFromSettings(userSettings, - group); - QSet matched; - matched.reserve(m_captainShortcuts.size()); - for (auto it = userShortcuts.begin(); it != userShortcuts.end(); ++it) { - auto defaultIt = m_captainShortcuts.find(it.key()); - if (defaultIt != m_captainShortcuts.end()) { - QString sequence = it.value().trimmed(); - if (sequence != defaultIt.value()) { - if (isValidKeySequence(sequence)) { - matched.insert(it.key()); - *defaultIt = sequence; - } - } else { - matched.insert(it.key()); - } - } - } - - if (matched.size() < m_captainShortcuts.size()) { - writeShortcutsToSettings(userSettings, group, m_captainShortcuts); - } - - qDebug() << "captain mode shortcuts:" << m_captainShortcuts; -} - -void VConfigManager::writeShortcutsToSettings(QSettings *p_settings, - const QString &p_group, - const QHash &p_shortcuts) -{ - p_settings->beginGroup(p_group); - p_settings->remove(""); - - for (auto it = p_shortcuts.begin(); it != p_shortcuts.end(); ++it) { - p_settings->setValue(it.key(), it.value()); - } - - p_settings->endGroup(); -} - -QString VConfigManager::getShortcutKeySequence(const QString &p_operation) const -{ - auto it = m_shortcuts.find(p_operation); - if (it == m_shortcuts.end()) { - return QString(); - } - - return *it; -} - -QString VConfigManager::getCaptainShortcutKeySequence(const QString &p_operation) const -{ - auto it = m_captainShortcuts.find(p_operation); - if (it == m_captainShortcuts.end()) { - return QString(); - } - - return *it; -} - -void VConfigManager::initDocSuffixes() -{ - m_docSuffixes.clear(); - - QString mdSuffix = getConfigFromSettings("global", - "markdown_suffix").toString(); - if (mdSuffix.isEmpty()) { - mdSuffix = getDefaultConfig("global", - "markdown_suffix").toString(); - } - - Q_ASSERT(!mdSuffix.isEmpty()); - QList md = mdSuffix.toLower().split(':', QString::SkipEmptyParts); - md.removeDuplicates(); - m_docSuffixes[(int)DocType::Markdown] = md; - - QList list; - list << "ls" << "list"; - m_docSuffixes[(int)DocType::List] = list; - - QList container; - container << "co" << "container" << "con"; - m_docSuffixes[(int)DocType::Container] = container; - - QList html; - html << "html"; - m_docSuffixes[(int)DocType::Html] = html; - - qDebug() << "doc suffixes" << m_docSuffixes; -} - -QVector VConfigManager::getLastOpenedFiles() -{ - QVector files; - int size = m_sessionSettings->beginReadArray("last_opened_files"); - for (int i = 0; i < size; ++i) { - m_sessionSettings->setArrayIndex(i); - files.push_back(VFileSessionInfo::fromSettings(m_sessionSettings)); - } - - m_sessionSettings->endArray(); - qDebug() << "read" << files.size() - << "items from [last_opened_files] section"; - - return files; -} - -void VConfigManager::setLastOpenedFiles(const QVector &p_files) -{ - const QString section("last_opened_files"); - - // Clear it first - m_sessionSettings->beginGroup(section); - m_sessionSettings->remove(""); - m_sessionSettings->endGroup(); - - m_sessionSettings->beginWriteArray(section); - for (int i = 0; i < p_files.size(); ++i) { - m_sessionSettings->setArrayIndex(i); - const VFileSessionInfo &info = p_files[i]; - info.toSettings(m_sessionSettings); - } - - m_sessionSettings->endArray(); - qDebug() << "write" << p_files.size() - << "items in [last_opened_files] section"; - -} - -QVector VConfigManager::getCustomMagicWords() -{ - QVector words; - int size = userSettings->beginReadArray("magic_words"); - for (int i = 0; i < size; ++i) { - userSettings->setArrayIndex(i); - - VMagicWord word; - word.m_name = userSettings->value("name").toString(); - word.m_definition = userSettings->value("definition").toString(); - words.push_back(word); - } - - userSettings->endArray(); - - return words; -} - -QVector> VConfigManager::getExternalEditors() const -{ - QVector> ret; - userSettings->beginGroup("external_editors"); - QStringList keys = userSettings->childKeys(); - for (auto const & key : keys) { - if (key.isEmpty()) { - continue; - } - - ret.push_back(QPair(key, userSettings->value(key).toString())); - } - - userSettings->endGroup(); - - return ret; -} - -const QString &VConfigManager::getFlashPage() const -{ - if (m_flashPage.isEmpty()) { - VConfigManager *var = const_cast(this); - - var->m_flashPage = var->getConfigFromSettings("global", - "flash_page").toString(); - if (var->m_flashPage.isEmpty()) { - var->m_flashPage = var->resetDefaultConfig("global", "flash_page").toString(); - } - - if (VUtils::checkFileNameLegal(m_flashPage)) { - var->m_flashPage = QDir(getConfigFolder()).filePath(m_flashPage); - } - } - - if (!QFileInfo::exists(m_flashPage)) { - VUtils::touchFile(m_flashPage); - } - - return m_flashPage; -} - -void VConfigManager::initThemes() -{ - m_themes.clear(); - - // Built-in. - QString file(":/resources/themes/v_white/v_white.palette"); - m_themes.insert(VPalette::themeName(file), file); - file = ":/resources/themes/v_pure/v_pure.palette"; - m_themes.insert(VPalette::themeName(file), file); - file = ":/resources/themes/v_moonlight/v_moonlight.palette"; - m_themes.insert(VPalette::themeName(file), file); - - /* NOT ready yet. Wait for author's tuning. - file = ":/resources/themes/v_material/v_material.palette"; - m_themes.insert(VPalette::themeName(file), file); - */ - - // User theme folder. - QDir dir(getThemeConfigFolder()); - if (!dir.exists()) { - dir.mkpath(getThemeConfigFolder()); - return; - } - - dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); - QStringList dirs = dir.entryList(); - for (auto const &item : dirs) { - QDir themeDir(dir.filePath(item)); - QStringList files = themeDir.entryList(QStringList() << "*.palette"); - if (files.size() != 1) { - continue; - } - - QFileInfo fi(files[0]); - m_themes.insert(VPalette::themeName(files[0]), themeDir.filePath(files[0])); - } -} - -void VConfigManager::initEditorStyles() -{ - Q_ASSERT(!m_themes.isEmpty()); - - // Styles from themes. - m_editorStyles = VPalette::editorStylesFromThemes(m_themes.values()); - - // User style folder. - // Get all the .mdhl files in the folder. - QDir dir(getStyleConfigFolder()); - if (!dir.exists()) { - dir.mkpath(getStyleConfigFolder()); - return; - } - - dir.setFilter(QDir::Files | QDir::NoSymLinks); - dir.setNameFilters(QStringList("*.mdhl")); - QStringList files = dir.entryList(); - for (auto const &item : files) { - QFileInfo fi(item); - m_editorStyles.insert(fi.completeBaseName(), dir.filePath(item)); - } -} - -void VConfigManager::initCssStyles() -{ - Q_ASSERT(!m_themes.isEmpty()); - - // Styles from themes. - m_cssStyles = VPalette::cssStylesFromThemes(m_themes.values()); - - // User style folder. - // Get all the .css files in the folder. - QDir dir(getStyleConfigFolder()); - if (!dir.exists()) { - dir.mkpath(getStyleConfigFolder()); - return; - } - - dir.setFilter(QDir::Files | QDir::NoSymLinks); - dir.setNameFilters(QStringList("*.css")); - QStringList files = dir.entryList(); - for (auto const &item : files) { - QFileInfo fi(item); - m_cssStyles.insert(fi.completeBaseName(), dir.filePath(item)); - } -} - -void VConfigManager::initCodeBlockCssStyles() -{ - Q_ASSERT(!m_themes.isEmpty()); - - // Styles from themes. - m_codeBlockCssStyles = VPalette::codeBlockCssStylesFromThemes(m_themes.values()); - - // User style folder. - // Get all the .css files in the folder. - QDir dir(getCodeBlockStyleConfigFolder()); - if (!dir.exists()) { - dir.mkpath(getCodeBlockStyleConfigFolder()); - return; - } - - dir.setFilter(QDir::Files | QDir::NoSymLinks); - dir.setNameFilters(QStringList("*.css")); - QStringList files = dir.entryList(); - for (auto const &item : files) { - QFileInfo fi(item); - m_codeBlockCssStyles.insert(fi.completeBaseName(), dir.filePath(item)); - } -} diff --git a/src/vconfigmanager.h b/src/vconfigmanager.h deleted file mode 100644 index 0b3e58a2..00000000 --- a/src/vconfigmanager.h +++ /dev/null @@ -1,1914 +0,0 @@ -#ifndef VCONFIGMANAGER_H -#define VCONFIGMANAGER_H - -#include -#include -#include -#include -#include -#include -#include "vnotebook.h" -#include "hgmarkdownhighlighter.h" -#include "vmarkdownconverter.h" -#include "vconstants.h" -#include "vfilesessioninfo.h" -#include "utils/vmetawordmanager.h" - - -class QJsonObject; -class QString; - -enum MarkdownConverterType -{ - Hoedown = 0, - Marked, - MarkdownIt, - Showdown -}; - -struct VColor -{ - QString name; - QString rgb; // 'FFFFFF', without '#' -}; - -struct MarkdownitOption -{ - MarkdownitOption(bool p_html, bool p_breaks, bool p_linkify) - : m_html(p_html), m_breaks(p_breaks), m_linkify(p_linkify) - { - } - - bool m_html; - bool m_breaks; - bool m_linkify; -}; - -// Type of heading sequence. -enum class HeadingSequenceType -{ - Disabled = 0, - Enabled, - - // Enabled only for internal notes. - EnabledNoteOnly, - - Invalid -}; - -class VConfigManager : public QObject -{ -public: - explicit VConfigManager(QObject *p_parent = NULL); - - void initialize(); - - // Read config from the directory config json file into a QJsonObject. - // @path is the directory containing the config json file. - static QJsonObject readDirectoryConfig(const QString &path); - - static bool writeDirectoryConfig(const QString &path, const QJsonObject &configJson); - static bool directoryConfigExist(const QString &path); - static bool deleteDirectoryConfig(const QString &path); - - // Get the path of the folder used to store default notebook. - static QString getVnoteNotebookFolderPath(); - - // Constants - static const QString orgName; - static const QString appName; - static const QString c_version; - - // CSS style for Warning texts. - static const QString c_warningTextStyle; - - // CSS style for data in label. - static const QString c_dataTextStyle; - - QFont getMdEditFont() const; - - QPalette getMdEditPalette() const; - - QVector getMdHighlightingStyles() const; - - QHash getCodeBlockStyles() const; - - QString getWelcomePagePath() const; - - QString getLogFilePath() const; - - // Get the css style URL for web view. - QString getCssStyleUrl() const; - - QString getCodeBlockCssStyleUrl() const; - - const QString &getEditorStyle() const; - void setEditorStyle(const QString &p_style); - - const QString &getCssStyle() const; - void setCssStyle(const QString &p_style); - - const QString &getCodeBlockCssStyle() const; - void setCodeBlockCssStyle(const QString &p_style); - - QFont getBaseEditFont() const; - QPalette getBaseEditPalette() const; - - int getCurNotebookIndex() const; - void setCurNotebookIndex(int index); - - // Read [notebooks] section from settings into @p_notebooks. - void getNotebooks(QVector &p_notebooks, QObject *p_parent); - - // Write @p_notebooks to [notebooks] section into settings. - void setNotebooks(const QVector &p_notebooks); - - hoedown_extensions getMarkdownExtensions() const; - MarkdownConverterType getMdConverterType() const; - void setMarkdownConverterType(MarkdownConverterType type); - - int getTabStopWidth() const; - void setTabStopWidth(int tabStopWidth); - bool getIsExpandTab() const; - void setIsExpandTab(bool isExpandTab); - - bool getHighlightCursorLine() const; - void setHighlightCursorLine(bool p_cursorLine); - - bool getHighlightSelectedWord() const; - void setHighlightSelectedWord(bool p_selectedWord); - - bool getHighlightSearchedWord() const; - void setHighlightSearchedWord(bool p_searchedWord); - - bool getAutoIndent() const; - void setAutoIndent(bool p_autoIndent); - - bool getAutoList() const; - void setAutoList(bool p_autoList); - - const QVector &getPredefinedColors() const; - - const QString &getCurBackgroundColor() const; - void setCurBackgroundColor(const QString &colorName); - - const QString &getCurRenderBackgroundColor() const; - void setCurRenderBackgroundColor(const QString &colorName); - - bool getToolsDockChecked() const; - void setToolsDockChecked(bool p_checked); - - const QByteArray &getMainWindowGeometry() const; - void setMainWindowGeometry(const QByteArray &p_geometry); - - const QByteArray &getMainWindowState() const; - void setMainWindowState(const QByteArray &p_state); - - const QByteArray &getMainSplitterState() const; - void setMainSplitterState(const QByteArray &p_state); - - const QByteArray &getNaviSplitterState() const; - void setNaviSplitterState(const QByteArray &p_state); - - bool getFindCaseSensitive() const; - void setFindCaseSensitive(bool p_enabled); - - bool getFindWholeWordOnly() const; - void setFindWholeWordOnly(bool p_enabled); - - bool getFindRegularExpression() const; - void setFindRegularExpression(bool p_enabled); - - bool getFindIncrementalSearch() const; - void setFindIncrementalSearch(bool p_enabled); - - QString getLanguage() const; - void setLanguage(const QString &p_language); - - bool getEnableMermaid() const; - void setEnableMermaid(bool p_enabled); - - bool getEnableFlowchart() const; - void setEnableFlowchart(bool p_enabled); - - bool getEnableMathjax() const; - void setEnableMathjax(bool p_enabled); - - qreal getWebZoomFactor() const; - void setWebZoomFactor(qreal p_factor); - bool isCustomWebZoomFactor(); - - const QString &getEditorCurrentLineBg() const; - const QString &getEditorTrailingSpaceBg() const; - const QString &getEditorSelectedWordBg() const; - const QString &getEditorSearchedWordBg() const; - const QString &getEditorSearchedWordCursorBg() const; - const QString &getEditorIncrementalSearchedWordBg() const; - - const QString &getEditorVimNormalBg() const; - const QString &getEditorVimInsertBg() const; - const QString &getEditorVimVisualBg() const; - const QString &getEditorVimReplaceBg() const; - - bool getEnableCodeBlockHighlight() const; - void setEnableCodeBlockHighlight(bool p_enabled); - - bool getEnablePreviewImages() const; - void setEnablePreviewImages(bool p_enabled); - - bool getEnablePreviewImageConstraint() const; - void setEnablePreviewImageConstraint(bool p_enabled); - - bool getEnableImageConstraint() const; - void setEnableImageConstraint(bool p_enabled); - - bool getEnableImageCaption() const; - void setEnableImageCaption(bool p_enabled); - - const QString &getImageFolder() const; - // Empty string to reset the default folder. - void setImageFolder(const QString &p_folder); - bool isCustomImageFolder() const; - - const QString &getImageFolderExt() const; - // Empty string to reset the default folder. - void setImageFolderExt(const QString &p_folder); - bool isCustomImageFolderExt() const; - - const QString &getAttachmentFolder() const; - // Empty string to reset the default folder. - void setAttachmentFolder(const QString &p_folder); - bool isCustomAttachmentFolder() const; - - bool getEnableTrailingSpaceHighlight() const; - void setEnableTrailingSapceHighlight(bool p_enabled); - - bool getEnableVimMode() const; - void setEnableVimMode(bool p_enabled); - - bool getEnableSmartImInVimMode() const; - void setEnableSmartImInVimMode(bool p_enabled); - - int getEditorLineNumber() const; - void setEditorLineNumber(int p_mode); - - const QString &getEditorLineNumberBg() const; - const QString &getEditorLineNumberFg() const; - - int getMinimizeToStystemTray() const; - void setMinimizeToSystemTray(int p_val); - - void initDocSuffixes(); - const QHash> &getDocSuffixes() const; - - int getMarkdownHighlightInterval() const; - - int getLineDistanceHeight() const; - - bool getInsertTitleFromNoteName() const; - void setInsertTitleFromNoteName(bool p_enabled); - - OpenFileMode getNoteOpenMode() const; - void setNoteOpenMode(OpenFileMode p_mode); - - HeadingSequenceType getHeadingSequenceType() const; - void setHeadingSequenceType(HeadingSequenceType p_type); - - int getHeadingSequenceBaseLevel() const; - void setHeadingSequenceBaseLevel(int p_level); - - int getColorColumn() const; - void setColorColumn(int p_column); - - const QString &getEditorColorColumnBg() const; - const QString &getEditorColorColumnFg() const; - - const QString &getEditorPreviewImageLineFg() const; - - bool getEnableCodeBlockLineNumber() const; - void setEnableCodeBlockLineNumber(bool p_enabled); - - int getToolBarIconSize() const; - - MarkdownitOption getMarkdownitOption() const; - void setMarkdownitOption(const MarkdownitOption &p_opt); - - const QString &getRecycleBinFolder() const; - - const QString &getRecycleBinFolderExt() const; - - bool getConfirmImagesCleanUp() const; - void setConfirmImagesCleanUp(bool p_enabled); - - bool getConfirmReloadFolder() const; - void setConfirmReloadFolder(bool p_enabled); - - const QString &getMathjaxJavascript() const; - - bool getDoubleClickCloseTab() const; - - bool getEnableCompactMode() const; - void setEnableCompactMode(bool p_enabled); - - StartupPageType getStartupPageType() const; - void setStartupPageType(StartupPageType p_type); - - const QStringList &getStartupPages() const; - void setStartupPages(const QStringList &p_pages); - - // Read last opened files from [last_opened_files] of session.ini. - QVector getLastOpenedFiles(); - - // Write last opened files to [last_opened_files] of session.ini. - void setLastOpenedFiles(const QVector &p_files); - - // Read custom magic words from [magic_words] section. - QVector getCustomMagicWords(); - - // Return the configured key sequence of @p_operation. - // Return empty if there is no corresponding config. - QString getShortcutKeySequence(const QString &p_operation) const; - - // Return the configured key sequence in Captain mode. - // Return empty if there is no corresponding config. - QString getCaptainShortcutKeySequence(const QString &p_operation) const; - - // Get the folder the ini file exists. - QString getConfigFolder() const; - - // Get the ini config file path. - QString getConfigFilePath() const; - - // Get the folder c_styleConfigFolder in the config folder. - const QString &getStyleConfigFolder() const; - - // Get the folder c_templateConfigFolder in the config folder. - const QString &getTemplateConfigFolder() const; - - // Get the folder c_themeConfigFolder in the config folder. - const QString &getThemeConfigFolder() const; - - // Get the folder c_snippetConfigFolder in the config folder. - const QString &getSnippetConfigFolder() const; - - const QString &getSnippetConfigFilePath() const; - - // Read all available templates files in c_templateConfigFolder. - QVector getNoteTemplates(DocType p_type = DocType::Unknown) const; - - // Get the folder c_codeBlockStyleConfigFolder in the config folder. - const QString &getCodeBlockStyleConfigFolder() const; - - // All the editor styles. - QList getEditorStyles() const; - - // All the css styles. - QList getCssStyles() const; - - // All the css styles. - QList getCodeBlockCssStyles() const; - - // Return the timer interval for checking file. - int getFileTimerInterval() const; - - // Get the backup directory. - const QString &getBackupDirectory() const; - - // Get the backup file extension. - const QString &getBackupExtension() const; - - // Whether backup file is enabled. - bool getEnableBackupFile() const; - - // Get defined external editors. - QVector> getExternalEditors() const; - - const QString &getVimExemptionKeys() const; - - const QString &getFlashPage() const; - - // All the themes. - QList getThemes() const; - - // Return current theme name. - const QString &getTheme() const; - - void setTheme(const QString &p_theme); - - QString getThemeFile() const; - -private: - // Look up a config from user and default settings. - QVariant getConfigFromSettings(const QString §ion, const QString &key) const; - - // Set a config to user settings. - void setConfigToSettings(const QString §ion, const QString &key, const QVariant &value); - - // Get default config from vnote.ini. - QVariant getDefaultConfig(const QString &p_section, const QString &p_key) const; - - // Reset user config to default config and return the default config value. - QVariant resetDefaultConfig(const QString &p_section, const QString &p_key); - - // Look up a config from session settings. - QVariant getConfigFromSessionSettings(const QString &p_section, const QString &p_key) const; - - // Set a config to session settings. - void setConfigToSessionSettings(const QString &p_section, - const QString &p_key, - const QVariant &p_value); - - // Init defaultSettings, userSettings, and m_sessionSettings. - void initSettings(); - - // Init from m_sessionSettings. - void initFromSessionSettings(); - - // Read [notebooks] section from @p_settings. - void readNotebookFromSettings(QSettings *p_settings, - QVector &p_notebooks, - QObject *parent); - - // Write to [notebooks] section to @p_settings. - void writeNotebookToSettings(QSettings *p_settings, - const QVector &p_notebooks); - - void readPredefinedColorsFromSettings(); - - // 1. Update styles common in HTML and Markdown; - // 2. Update styles for Markdown. - void updateEditStyle(); - - void updateMarkdownEditStyle(); - - // See if the old c_obsoleteDirConfigFile exists. If so, rename it to - // the new one; if not, use the c_dirConfigFile. - static QString fetchDirConfigFilePath(const QString &p_path); - - // Read the [shortcuts] section in settings to init m_shortcuts. - // Will remove invalid config items. - // First read the config in default settings; - // Second read the config in user settings and overwrite the default ones; - // If there is any config in deafult settings that is absent in user settings, - // write the combined configs to user settings. - void readShortcutsFromSettings(); - - // Read the [captain_mode_shortcuts] section in the settings to init - // m_captainShortcuts. - void readCaptainShortcutsFromSettings(); - - QHash readShortcutsFromSettings(QSettings *p_settings, - const QString &p_group); - - void writeShortcutsToSettings(QSettings *p_settings, - const QString &p_group, - const QHash &p_shortcuts); - - // Whether @p_seq is a valid key sequence for shortcuts. - bool isValidKeySequence(const QString &p_seq); - - // Init the themes name-file mappings. - void initThemes(); - - // Init the editor styles name-file mappings. - void initEditorStyles(); - - void initCssStyles(); - - void initCodeBlockCssStyles(); - - QString getEditorStyleFile() const; - - // Default font and palette. - QFont m_defaultEditFont; - QPalette m_defaultEditPalette; - - // Font and palette used for non-markdown editor. - QFont baseEditFont; - QPalette baseEditPalette; - - // Font and palette used for markdown editor. - QFont mdEditFont; - QPalette mdEditPalette; - - QVector mdHighlightingStyles; - QHash m_codeBlockStyles; - - QString welcomePagePath; - - // Index of current notebook. - int curNotebookIndex; - - // Markdown Converter - hoedown_extensions markdownExtensions; - MarkdownConverterType mdConverterType; - - // Num of spaces - int tabStopWidth; - // Expand tab to @tabStopWidth spaces - bool isExpandTab; - - // Highlight current cursor line. - bool m_highlightCursorLine; - - // Highlight selected word. - bool m_highlightSelectedWord; - - // Highlight searched word. - bool m_highlightSearchedWord; - - // Auto Indent. - bool m_autoIndent; - - // Auto List. - bool m_autoList; - - // App defined color - QVector predefinedColors; - QString curBackgroundColor; - QString curRenderBackgroundColor; - - bool m_toolsDockChecked; - - QByteArray m_mainWindowGeometry; - QByteArray m_mainWindowState; - QByteArray m_mainSplitterState; - QByteArray m_naviSplitterState; - - // Find/Replace dialog options - bool m_findCaseSensitive; - bool m_findWholeWordOnly; - bool m_findRegularExpression; - bool m_findIncrementalSearch; - - // Language - QString m_language; - - // Enable Mermaid. - bool m_enableMermaid; - - // Enable flowchart.js. - bool m_enableFlowchart; - - // Enable Mathjax. - bool m_enableMathjax; - - // Zoom factor of the QWebEngineView. - qreal m_webZoomFactor; - - // Current line background color in editor. - QString m_editorCurrentLineBg; - - // Current line background color in editor in Vim normal mode. - QString m_editorVimNormalBg; - - // Current line background color in editor in Vim insert mode. - QString m_editorVimInsertBg; - - // Current line background color in editor in Vim visual mode. - QString m_editorVimVisualBg; - - // Current line background color in editor in Vim replace mode. - QString m_editorVimReplaceBg; - - // Trailing space background color in editor. - QString m_editorTrailingSpaceBg; - - // Background color of selected word in editor. - QString m_editorSelectedWordBg; - - // Background color of searched word in editor. - QString m_editorSearchedWordBg; - - // Background color of searched word under cursor in editor. - QString m_editorSearchedWordCursorBg; - - // Background color of incremental searched word in editor. - QString m_editorIncrementalSearchedWordBg; - - // Enable colde block syntax highlight. - bool m_enableCodeBlockHighlight; - - // Preview images in edit mode. - bool m_enablePreviewImages; - - // Constrain the width of image preview in edit mode. - bool m_enablePreviewImageConstraint; - - // Constrain the width of image in read mode. - bool m_enableImageConstraint; - - // Center image and add the alt text as caption. - bool m_enableImageCaption; - - // Global default folder name to store images of all the notes. - // Each notebook can specify its custom folder. - QString m_imageFolder; - - // Global default folder name to store images of all external files. - // Each file can specify its custom folder. - QString m_imageFolderExt; - - // Global default folder name to store attachments of all the notes. - // Each notebook can specify its custom folder. - QString m_attachmentFolder; - - // Enable trailing-space highlight. - bool m_enableTrailingSpaceHighlight; - - // Enable Vim mode. - bool m_enableVimMode; - - // Enable smart input method in Vim mode. - bool m_enableSmartImInVimMode; - - // Editor line number mode. - int m_editorLineNumber; - - // The background color of the line number area. - QString m_editorLineNumberBg; - - // The foreground color of the line number area. - QString m_editorLineNumberFg; - - // Shortcuts config. - // Operation -> KeySequence. - QHash m_shortcuts; - - // Shortcuts config in Captain mode. - // Operation -> KeySequence. - QHash m_captainShortcuts; - - // Whether minimize to system tray icon when closing the app. - // -1: uninitialized; - // 0: do not minimize to the tay; - // 1: minimize to the tray. - int m_minimizeToSystemTray; - - // Suffixes of different doc type. - // [DocType] -> { Suffixes }. - QHash> m_docSuffixes; - - // Interval for HGMarkdownHighlighter highlight timer (milliseconds). - int m_markdownHighlightInterval; - - // Line distance height in pixel. - int m_lineDistanceHeight; - - // Whether insert the note name as a title when creating a new note. - bool m_insertTitleFromNoteName; - - // Default mode when opening a note. - OpenFileMode m_noteOpenMode; - - // Whether auto genearte heading sequence. - HeadingSequenceType m_headingSequenceType; - - // Heading sequence base level. - int m_headingSequenceBaseLevel; - - // The column to style in code block. - int m_colorColumn; - - // Whether display line number of code block in read mode. - bool m_enableCodeBlockLineNumber; - - // The background color of the color column. - QString m_editorColorColumnBg; - - // The foreground color of the color column. - QString m_editorColorColumnFg; - - // The foreground color of the preview image line. - QString m_editorPreviewImageLineFg; - - // Icon size of tool bar in pixels. - int m_toolBarIconSize; - - // Eanble HTML tags in source. - bool m_markdownitOptHtml; - - // Convert '\n' in paragraphs into
    . - bool m_markdownitOptBreaks; - - // Auto-convert URL-like text to links. - bool m_markdownitOptLinkify; - - // Default name of the recycle bin folder of notebook. - QString m_recycleBinFolder; - - // Default name of the recycle bin folder of external files. - QString m_recycleBinFolderExt; - - // Confirm before deleting unused images. - bool m_confirmImagesCleanUp; - - // Confirm before reloading folder from disk. - bool m_confirmReloadFolder; - - // Location and configuration for Mathjax. - QString m_mathjaxJavascript; - - // Whether double click on a tab to close it. - bool m_doubleClickCloseTab; - - // Whether put folder and note panel in one single column. - bool m_enableCompactMode; - - // Type of the pages to open on startup. - StartupPageType m_startupPageType; - - // File paths to open on startup. - QStringList m_startupPages; - - // Timer interval to check file in milliseconds. - int m_fileTimerInterval; - - // Directory for the backup file (relative or absolute path). - QString m_backupDirectory; - - // Extension of the backup file. - QString m_backupExtension; - - // Whether enable backup file. - bool m_enableBackupFile; - - // Skipped keys in Vim mode. - // c: Ctrl+C - // v: Ctrl+V - QString m_vimExemptionKeys; - - // Absolute path of flash page. - QString m_flashPage; - - // The theme name. - QString m_theme; - - // All the themes. - // [name] -> [file path]. - QMap m_themes; - - // The editor style name. - QString m_editorStyle; - - // All the editor styles. - // [name] -> [file path]. - QMap m_editorStyles; - - // The web view css style name. - QString m_cssStyle; - - // All the css styles. - // [name] -> [file path]. - QMap m_cssStyles; - - // The web view code block css style name. - QString m_codeBlockCssStyle; - - // All the css styles. - // [name] -> [file path]. - QMap m_codeBlockCssStyles; - - // The name of the config file in each directory, obsolete. - // Use c_dirConfigFile instead. - static const QString c_obsoleteDirConfigFile; - - // The name of the config file in each directory. - static const QString c_dirConfigFile; - - // The path of the default configuration file - static const QString c_defaultConfigFilePath; - - // The name of the config file. - static const QString c_defaultConfigFile; - - // The name of the config file for session information. - static const QString c_sessionConfigFile; - - // The name of the config file for snippets folder. - static const QString c_snippetConfigFile; - - // QSettings for the user configuration - QSettings *userSettings; - - // Qsettings for @c_defaultConfigFilePath. - QSettings *defaultSettings; - - // QSettings for the session configuration, such as notebooks, - // geometry, last opened files. - QSettings *m_sessionSettings; - - // The folder name of style files. - static const QString c_styleConfigFolder; - - // The folder name of theme files. - static const QString c_themeConfigFolder; - - // The folder name of code block style files. - static const QString c_codeBlockStyleConfigFolder; - - // The folder name of template files. - static const QString c_templateConfigFolder; - - // The folder name of snippet files. - static const QString c_snippetConfigFolder; - - // The folder name to store all notebooks if user does not specify one. - static const QString c_vnoteNotebookFolderName; -}; - - -inline QFont VConfigManager::getMdEditFont() const -{ - return mdEditFont; -} - -inline QPalette VConfigManager::getMdEditPalette() const -{ - return mdEditPalette; -} - -inline QVector VConfigManager::getMdHighlightingStyles() const -{ - return mdHighlightingStyles; -} - -inline QHash VConfigManager::getCodeBlockStyles() const -{ - return m_codeBlockStyles; -} - -inline QString VConfigManager::getWelcomePagePath() const -{ - return welcomePagePath; -} - -inline QFont VConfigManager::getBaseEditFont() const -{ - return baseEditFont; -} - -inline QPalette VConfigManager::getBaseEditPalette() const -{ - return baseEditPalette; -} - -inline int VConfigManager::getCurNotebookIndex() const -{ - return curNotebookIndex; -} - -inline void VConfigManager::setCurNotebookIndex(int index) -{ - if (index == curNotebookIndex) { - return; - } - - curNotebookIndex = index; - setConfigToSessionSettings("global", "current_notebook", index); -} - -inline void VConfigManager::getNotebooks(QVector &p_notebooks, - QObject *p_parent) -{ - // We used to store it in vnote.ini. For now, we store it in session.ini. - readNotebookFromSettings(m_sessionSettings, p_notebooks, p_parent); - - // Migration. - if (p_notebooks.isEmpty()) { - readNotebookFromSettings(userSettings, p_notebooks, p_parent); - - if (!p_notebooks.isEmpty()) { - // Clear and save it in another place. - userSettings->beginGroup("notebooks"); - userSettings->remove(""); - userSettings->endGroup(); - - writeNotebookToSettings(m_sessionSettings, p_notebooks); - } - } -} - -inline void VConfigManager::setNotebooks(const QVector &p_notebooks) -{ - writeNotebookToSettings(m_sessionSettings, p_notebooks); -} - -inline hoedown_extensions VConfigManager::getMarkdownExtensions() const -{ - return markdownExtensions; -} - -inline MarkdownConverterType VConfigManager::getMdConverterType() const -{ - return mdConverterType; -} - -inline void VConfigManager::setMarkdownConverterType(MarkdownConverterType type) -{ - if (mdConverterType == type) { - return; - } - mdConverterType = type; - setConfigToSettings("global", "markdown_converter", type); -} - -inline int VConfigManager::getTabStopWidth() const -{ - return tabStopWidth; -} - -inline bool VConfigManager::getIsExpandTab() const -{ - return isExpandTab; -} - -inline void VConfigManager::setTabStopWidth(int tabStopWidth) -{ - if (tabStopWidth == this->tabStopWidth) { - return; - } - this->tabStopWidth = tabStopWidth; - setConfigToSettings("global", "tab_stop_width", tabStopWidth); -} - -inline void VConfigManager::setIsExpandTab(bool isExpandTab) -{ - if (isExpandTab == this->isExpandTab) { - return; - } - this->isExpandTab = isExpandTab; - setConfigToSettings("global", "is_expand_tab", this->isExpandTab); -} - -inline bool VConfigManager::getHighlightCursorLine() const -{ - return m_highlightCursorLine; -} - -inline void VConfigManager::setHighlightCursorLine(bool p_cursorLine) -{ - if (p_cursorLine == m_highlightCursorLine) { - return; - } - m_highlightCursorLine = p_cursorLine; - setConfigToSettings("global", "highlight_cursor_line", m_highlightCursorLine); -} - -inline bool VConfigManager::getHighlightSelectedWord() const -{ - return m_highlightSelectedWord; -} - -inline void VConfigManager::setHighlightSelectedWord(bool p_selectedWord) -{ - if (p_selectedWord == m_highlightSelectedWord) { - return; - } - m_highlightSelectedWord = p_selectedWord; - setConfigToSettings("global", "highlight_selected_word", - m_highlightSelectedWord); -} - -inline bool VConfigManager::getHighlightSearchedWord() const -{ - return m_highlightSearchedWord; -} - -inline void VConfigManager::setHighlightSearchedWord(bool p_searchedWord) -{ - if (p_searchedWord == m_highlightSearchedWord) { - return; - } - m_highlightSearchedWord = p_searchedWord; - setConfigToSettings("global", "highlight_searched_word", - m_highlightSearchedWord); -} - -inline bool VConfigManager::getAutoIndent() const -{ - return m_autoIndent; -} - -inline void VConfigManager::setAutoIndent(bool p_autoIndent) -{ - if (m_autoIndent == p_autoIndent) { - return; - } - m_autoIndent = p_autoIndent; - setConfigToSettings("global", "auto_indent", - m_autoIndent); -} - -inline bool VConfigManager::getAutoList() const -{ - return m_autoList; -} - -inline void VConfigManager::setAutoList(bool p_autoList) -{ - if (m_autoList == p_autoList) { - return; - } - m_autoList = p_autoList; - setConfigToSettings("global", "auto_list", - m_autoList); -} - -inline const QVector& VConfigManager::getPredefinedColors() const -{ - return predefinedColors; -} - -inline const QString& VConfigManager::getCurBackgroundColor() const -{ - return curBackgroundColor; -} - -inline void VConfigManager::setCurBackgroundColor(const QString &colorName) -{ - if (curBackgroundColor == colorName) { - return; - } - curBackgroundColor = colorName; - setConfigToSettings("global", "current_background_color", - curBackgroundColor); - updateEditStyle(); -} - -inline const QString& VConfigManager::getCurRenderBackgroundColor() const -{ - return curRenderBackgroundColor; -} - -inline void VConfigManager::setCurRenderBackgroundColor(const QString &colorName) -{ - if (curRenderBackgroundColor == colorName) { - return; - } - curRenderBackgroundColor = colorName; - setConfigToSettings("global", "current_render_background_color", - curRenderBackgroundColor); -} - -inline bool VConfigManager::getToolsDockChecked() const -{ - return m_toolsDockChecked; -} - -inline void VConfigManager::setToolsDockChecked(bool p_checked) -{ - m_toolsDockChecked = p_checked; - setConfigToSettings("global", "tools_dock_checked", - m_toolsDockChecked); -} - -inline const QByteArray& VConfigManager::getMainWindowGeometry() const -{ - return m_mainWindowGeometry; -} - -inline void VConfigManager::setMainWindowGeometry(const QByteArray &p_geometry) -{ - m_mainWindowGeometry = p_geometry; - setConfigToSessionSettings("geometry", - "main_window_geometry", - m_mainWindowGeometry); -} - -inline const QByteArray& VConfigManager::getMainWindowState() const -{ - return m_mainWindowState; -} - -inline void VConfigManager::setMainWindowState(const QByteArray &p_state) -{ - m_mainWindowState = p_state; - setConfigToSessionSettings("geometry", - "main_window_state", - m_mainWindowState); -} - -inline const QByteArray& VConfigManager::getMainSplitterState() const -{ - return m_mainSplitterState; -} - -inline void VConfigManager::setMainSplitterState(const QByteArray &p_state) -{ - m_mainSplitterState = p_state; - setConfigToSessionSettings("geometry", - "main_splitter_state", - m_mainSplitterState); -} - -inline const QByteArray& VConfigManager::getNaviSplitterState() const -{ - return m_naviSplitterState; -} - -inline void VConfigManager::setNaviSplitterState(const QByteArray &p_state) -{ - m_naviSplitterState = p_state; - setConfigToSessionSettings("geometry", - "navi_splitter_state", - m_naviSplitterState); -} - -inline bool VConfigManager::getFindCaseSensitive() const -{ - return m_findCaseSensitive; -} - -inline void VConfigManager::setFindCaseSensitive(bool p_enabled) -{ - if (m_findCaseSensitive == p_enabled) { - return; - } - m_findCaseSensitive = p_enabled; - setConfigToSettings("global", "find_case_sensitive", m_findCaseSensitive); -} - -inline bool VConfigManager::getFindWholeWordOnly() const -{ - return m_findWholeWordOnly; -} - -inline void VConfigManager::setFindWholeWordOnly(bool p_enabled) -{ - if (m_findWholeWordOnly == p_enabled) { - return; - } - m_findWholeWordOnly = p_enabled; - setConfigToSettings("global", "find_whole_word_only", m_findWholeWordOnly); -} - -inline bool VConfigManager::getFindRegularExpression() const -{ - return m_findRegularExpression; -} - -inline void VConfigManager::setFindRegularExpression(bool p_enabled) -{ - if (m_findRegularExpression == p_enabled) { - return; - } - m_findRegularExpression = p_enabled; - setConfigToSettings("global", "find_regular_expression", - m_findRegularExpression); -} - -inline bool VConfigManager::getFindIncrementalSearch() const -{ - return m_findIncrementalSearch; -} - -inline void VConfigManager::setFindIncrementalSearch(bool p_enabled) -{ - if (m_findIncrementalSearch == p_enabled) { - return; - } - m_findIncrementalSearch = p_enabled; - setConfigToSettings("global", "find_incremental_search", - m_findIncrementalSearch); -} - -inline QString VConfigManager::getLanguage() const -{ - return m_language; -} - -inline void VConfigManager::setLanguage(const QString &p_language) -{ - if (m_language == p_language) { - return; - } - m_language = p_language; - setConfigToSettings("global", "language", - m_language); -} - -inline bool VConfigManager::getEnableMermaid() const -{ - return m_enableMermaid; -} - -inline void VConfigManager::setEnableMermaid(bool p_enabled) -{ - if (m_enableMermaid == p_enabled) { - return; - } - m_enableMermaid = p_enabled; - setConfigToSettings("global", "enable_mermaid", m_enableMermaid); -} - -inline bool VConfigManager::getEnableFlowchart() const -{ - return m_enableFlowchart; -} - -inline void VConfigManager::setEnableFlowchart(bool p_enabled) -{ - if (m_enableFlowchart == p_enabled) { - return; - } - - m_enableFlowchart = p_enabled; - setConfigToSettings("global", "enable_flowchart", m_enableFlowchart); -} - -inline bool VConfigManager::getEnableMathjax() const -{ - return m_enableMathjax; -} - -inline void VConfigManager::setEnableMathjax(bool p_enabled) -{ - if (m_enableMathjax == p_enabled) { - return; - } - m_enableMathjax = p_enabled; - setConfigToSettings("global", "enable_mathjax", m_enableMathjax); -} - -inline qreal VConfigManager::getWebZoomFactor() const -{ - return m_webZoomFactor; -} - -inline bool VConfigManager::isCustomWebZoomFactor() -{ - qreal factorFromIni = getConfigFromSettings("global", "web_zoom_factor").toReal(); - // -1 indicates let system automatically calculate the factor. - return factorFromIni > 0; -} - -inline const QString &VConfigManager::getEditorCurrentLineBg() const -{ - return m_editorCurrentLineBg; -} - -inline const QString &VConfigManager::getEditorTrailingSpaceBg() const -{ - return m_editorTrailingSpaceBg; -} - -inline const QString &VConfigManager::getEditorSelectedWordBg() const -{ - return m_editorSelectedWordBg; -} - -inline const QString &VConfigManager::getEditorSearchedWordBg() const -{ - return m_editorSearchedWordBg; -} - -inline const QString &VConfigManager::getEditorSearchedWordCursorBg() const -{ - return m_editorSearchedWordCursorBg; -} - -inline const QString &VConfigManager::getEditorIncrementalSearchedWordBg() const -{ - return m_editorIncrementalSearchedWordBg; -} - -inline const QString &VConfigManager::getEditorVimNormalBg() const -{ - return m_editorVimNormalBg; -} - -inline const QString &VConfigManager::getEditorVimInsertBg() const -{ - return m_editorVimInsertBg; -} - -inline const QString &VConfigManager::getEditorVimVisualBg() const -{ - return m_editorVimVisualBg; -} - -inline const QString &VConfigManager::getEditorVimReplaceBg() const -{ - return m_editorVimReplaceBg; -} - -inline bool VConfigManager::getEnableCodeBlockHighlight() const -{ - return m_enableCodeBlockHighlight; -} - -inline void VConfigManager::setEnableCodeBlockHighlight(bool p_enabled) -{ - if (m_enableCodeBlockHighlight == p_enabled) { - return; - } - m_enableCodeBlockHighlight = p_enabled; - setConfigToSettings("global", "enable_code_block_highlight", - m_enableCodeBlockHighlight); -} - -inline bool VConfigManager::getEnablePreviewImages() const -{ - return m_enablePreviewImages; -} - -inline void VConfigManager::setEnablePreviewImages(bool p_enabled) -{ - if (m_enablePreviewImages == p_enabled) { - return; - } - - m_enablePreviewImages = p_enabled; - setConfigToSettings("global", "enable_preview_images", - m_enablePreviewImages); -} - -inline bool VConfigManager::getEnablePreviewImageConstraint() const -{ - return m_enablePreviewImageConstraint; -} - -inline void VConfigManager::setEnablePreviewImageConstraint(bool p_enabled) -{ - if (m_enablePreviewImageConstraint == p_enabled) { - return; - } - - m_enablePreviewImageConstraint = p_enabled; - setConfigToSettings("global", "enable_preview_image_constraint", - m_enablePreviewImageConstraint); -} - -inline bool VConfigManager::getEnableImageConstraint() const -{ - return m_enableImageConstraint; -} - -inline void VConfigManager::setEnableImageConstraint(bool p_enabled) -{ - if (m_enableImageConstraint == p_enabled) { - return; - } - - m_enableImageConstraint = p_enabled; - setConfigToSettings("global", "enable_image_constraint", - m_enableImageConstraint); -} - -inline bool VConfigManager::getEnableImageCaption() const -{ - return m_enableImageCaption; -} - -inline void VConfigManager::setEnableImageCaption(bool p_enabled) -{ - if (m_enableImageCaption == p_enabled) { - return; - } - m_enableImageCaption = p_enabled; - setConfigToSettings("global", "enable_image_caption", - m_enableImageCaption); -} - -inline const QString &VConfigManager::getImageFolder() const -{ - return m_imageFolder; -} - -inline void VConfigManager::setImageFolder(const QString &p_folder) -{ - if (p_folder.isEmpty()) { - // Reset the default folder. - m_imageFolder = resetDefaultConfig("global", "image_folder").toString(); - return; - } - - if (m_imageFolder == p_folder) { - return; - } - - m_imageFolder = p_folder; - setConfigToSettings("global", "image_folder", m_imageFolder); -} - -inline bool VConfigManager::isCustomImageFolder() const -{ - return m_imageFolder != getDefaultConfig("global", "image_folder").toString(); -} - -inline const QString &VConfigManager::getImageFolderExt() const -{ - return m_imageFolderExt; -} - -inline void VConfigManager::setImageFolderExt(const QString &p_folder) -{ - if (p_folder.isEmpty()) { - // Reset the default folder. - m_imageFolderExt = resetDefaultConfig("global", "external_image_folder").toString(); - return; - } - - if (m_imageFolderExt == p_folder) { - return; - } - - m_imageFolderExt = p_folder; - setConfigToSettings("global", "external_image_folder", m_imageFolderExt); -} - -inline bool VConfigManager::isCustomImageFolderExt() const -{ - return m_imageFolderExt != getDefaultConfig("global", "external_image_folder").toString(); -} - -inline const QString &VConfigManager::getAttachmentFolder() const -{ - return m_attachmentFolder; -} - -inline void VConfigManager::setAttachmentFolder(const QString &p_folder) -{ - if (p_folder.isEmpty()) { - // Reset the default folder. - m_attachmentFolder = resetDefaultConfig("global", "attachment_folder").toString(); - return; - } - - if (m_attachmentFolder == p_folder) { - return; - } - - m_attachmentFolder = p_folder; - setConfigToSettings("global", "attachment_folder", m_attachmentFolder); -} - -inline bool VConfigManager::isCustomAttachmentFolder() const -{ - return m_attachmentFolder != getDefaultConfig("global", "attachment_folder").toString(); -} - -inline bool VConfigManager::getEnableTrailingSpaceHighlight() const -{ - return m_enableTrailingSpaceHighlight; -} - -inline void VConfigManager::setEnableTrailingSapceHighlight(bool p_enabled) -{ - if (m_enableTrailingSpaceHighlight == p_enabled) { - return; - } - - m_enableTrailingSpaceHighlight = p_enabled; - setConfigToSettings("global", "enable_trailing_space_highlight", - m_enableTrailingSpaceHighlight); -} - -inline bool VConfigManager::getEnableVimMode() const -{ - return m_enableVimMode; -} - -inline void VConfigManager::setEnableVimMode(bool p_enabled) -{ - if (m_enableVimMode == p_enabled) { - return; - } - - m_enableVimMode = p_enabled; - setConfigToSettings("global", "enable_vim_mode", - m_enableVimMode); -} - -inline bool VConfigManager::getEnableSmartImInVimMode() const -{ - return m_enableSmartImInVimMode; -} - -inline void VConfigManager::setEnableSmartImInVimMode(bool p_enabled) -{ - if (m_enableSmartImInVimMode == p_enabled) { - return; - } - - m_enableSmartImInVimMode = p_enabled; - setConfigToSettings("global", "enable_smart_im_in_vim_mode", - m_enableSmartImInVimMode); -} - -inline int VConfigManager::getEditorLineNumber() const -{ - return m_editorLineNumber; -} - -inline void VConfigManager::setEditorLineNumber(int p_mode) -{ - if (m_editorLineNumber == p_mode) { - return; - } - - m_editorLineNumber = p_mode; - setConfigToSettings("global", "editor_line_number", - m_editorLineNumber); -} - -inline const QString &VConfigManager::getEditorLineNumberBg() const -{ - return m_editorLineNumberBg; -} - -inline const QString &VConfigManager::getEditorLineNumberFg() const -{ - return m_editorLineNumberFg; -} - -inline int VConfigManager::getMinimizeToStystemTray() const -{ - return m_minimizeToSystemTray; -} - -inline void VConfigManager::setMinimizeToSystemTray(int p_val) -{ - if (m_minimizeToSystemTray == p_val) { - return; - } - - m_minimizeToSystemTray = p_val; - setConfigToSettings("global", "minimize_to_system_tray", - m_minimizeToSystemTray); -} - -inline const QHash> &VConfigManager::getDocSuffixes() const -{ - return m_docSuffixes; -} - -inline int VConfigManager::getMarkdownHighlightInterval() const -{ - return m_markdownHighlightInterval; -} - -inline int VConfigManager::getLineDistanceHeight() const -{ - return m_lineDistanceHeight; -} - -inline bool VConfigManager::getInsertTitleFromNoteName() const -{ - return m_insertTitleFromNoteName; -} - -inline void VConfigManager::setInsertTitleFromNoteName(bool p_enabled) -{ - if (p_enabled == m_insertTitleFromNoteName) { - return; - } - - m_insertTitleFromNoteName = p_enabled; - setConfigToSettings("global", "insert_title_from_note_name", - m_insertTitleFromNoteName); -} - -inline OpenFileMode VConfigManager::getNoteOpenMode() const -{ - return m_noteOpenMode; -} - -inline void VConfigManager::setNoteOpenMode(OpenFileMode p_mode) -{ - if (m_noteOpenMode == p_mode) { - return; - } - - m_noteOpenMode = p_mode; - setConfigToSettings("global", "note_open_mode", - m_noteOpenMode == OpenFileMode::Read ? 0 : 1); -} - -inline HeadingSequenceType VConfigManager::getHeadingSequenceType() const -{ - return m_headingSequenceType; -} - -inline void VConfigManager::setHeadingSequenceType(HeadingSequenceType p_type) -{ - if (m_headingSequenceType == p_type) { - return; - } - - m_headingSequenceType = p_type; - setConfigToSettings("global", - "heading_sequence_type", - (int)m_headingSequenceType); -} - -inline int VConfigManager::getHeadingSequenceBaseLevel() const -{ - return m_headingSequenceBaseLevel; -} - -inline void VConfigManager::setHeadingSequenceBaseLevel(int p_level) -{ - if (m_headingSequenceBaseLevel == p_level) { - return; - } - - m_headingSequenceBaseLevel = p_level; - setConfigToSettings("global", - "heading_sequence_base_level", - m_headingSequenceBaseLevel); -} - -inline int VConfigManager::getColorColumn() const -{ - return m_colorColumn; -} - -inline void VConfigManager::setColorColumn(int p_column) -{ - if (m_colorColumn == p_column) { - return; - } - - m_colorColumn = p_column; - setConfigToSettings("global", "color_column", m_colorColumn); -} - -inline const QString &VConfigManager::getEditorColorColumnBg() const -{ - return m_editorColorColumnBg; -} - -inline const QString &VConfigManager::getEditorColorColumnFg() const -{ - return m_editorColorColumnFg; -} - -inline const QString &VConfigManager::getEditorPreviewImageLineFg() const -{ - return m_editorPreviewImageLineFg; -} - -inline bool VConfigManager::getEnableCodeBlockLineNumber() const -{ - return m_enableCodeBlockLineNumber; -} - -inline void VConfigManager::setEnableCodeBlockLineNumber(bool p_enabled) -{ - if (m_enableCodeBlockLineNumber == p_enabled) { - return; - } - - m_enableCodeBlockLineNumber = p_enabled; - setConfigToSettings("global", - "enable_code_block_line_number", - m_enableCodeBlockLineNumber); -} - -inline int VConfigManager::getToolBarIconSize() const -{ - return m_toolBarIconSize; -} - -inline MarkdownitOption VConfigManager::getMarkdownitOption() const -{ - return MarkdownitOption(m_markdownitOptHtml, - m_markdownitOptBreaks, - m_markdownitOptLinkify); -} - -inline void VConfigManager::setMarkdownitOption(const MarkdownitOption &p_opt) -{ - if (m_markdownitOptHtml != p_opt.m_html) { - m_markdownitOptHtml = p_opt.m_html; - setConfigToSettings("global", - "markdownit_opt_html", - m_markdownitOptHtml); - } - - if (m_markdownitOptBreaks != p_opt.m_breaks) { - m_markdownitOptBreaks = p_opt.m_breaks; - setConfigToSettings("global", - "markdownit_opt_breaks", - m_markdownitOptBreaks); - } - - if (m_markdownitOptLinkify != p_opt.m_linkify) { - m_markdownitOptLinkify = p_opt.m_linkify; - setConfigToSettings("global", - "markdownit_opt_linkify", - m_markdownitOptLinkify); - } -} - -inline const QString &VConfigManager::getRecycleBinFolder() const -{ - return m_recycleBinFolder; -} - -inline const QString &VConfigManager::getRecycleBinFolderExt() const -{ - return m_recycleBinFolderExt; -} - -inline bool VConfigManager::getConfirmImagesCleanUp() const -{ - return m_confirmImagesCleanUp; -} - -inline void VConfigManager::setConfirmImagesCleanUp(bool p_enabled) -{ - if (m_confirmImagesCleanUp == p_enabled) { - return; - } - - m_confirmImagesCleanUp = p_enabled; - setConfigToSettings("global", - "confirm_images_clean_up", - m_confirmImagesCleanUp); -} - -inline bool VConfigManager::getConfirmReloadFolder() const -{ - return m_confirmReloadFolder; -} - -inline void VConfigManager::setConfirmReloadFolder(bool p_enabled) -{ - if (m_confirmReloadFolder == p_enabled) { - return; - } - - m_confirmReloadFolder = p_enabled; - setConfigToSettings("global", - "confirm_reload_folder", - m_confirmReloadFolder); -} - -inline const QString &VConfigManager::getMathjaxJavascript() const -{ - return m_mathjaxJavascript; -} - -inline bool VConfigManager::getDoubleClickCloseTab() const -{ - return m_doubleClickCloseTab; -} - -inline bool VConfigManager::getEnableCompactMode() const -{ - return m_enableCompactMode; -} - -inline void VConfigManager::setEnableCompactMode(bool p_enabled) -{ - if (m_enableCompactMode == p_enabled) { - return; - } - - m_enableCompactMode = p_enabled; - setConfigToSettings("global", "enable_compact_mode", m_enableCompactMode); -} - -inline StartupPageType VConfigManager::getStartupPageType() const -{ - return m_startupPageType; -} - -inline void VConfigManager::setStartupPageType(StartupPageType p_type) -{ - if (m_startupPageType == p_type) { - return; - } - - m_startupPageType = p_type; - setConfigToSettings("global", "startup_page_type", (int)m_startupPageType); -} - -inline const QStringList &VConfigManager::getStartupPages() const -{ - return m_startupPages; -} - -inline void VConfigManager::setStartupPages(const QStringList &p_pages) -{ - if (m_startupPages == p_pages) { - return; - } - - m_startupPages = p_pages; - setConfigToSettings("global", "startup_pages", m_startupPages); -} - -inline int VConfigManager::getFileTimerInterval() const -{ - return m_fileTimerInterval; -} - -inline const QString &VConfigManager::getBackupDirectory() const -{ - return m_backupDirectory; -} - -inline const QString &VConfigManager::getBackupExtension() const -{ - return m_backupExtension; -} - -inline bool VConfigManager::getEnableBackupFile() const -{ - return m_enableBackupFile; -} - -inline const QString &VConfigManager::getVimExemptionKeys() const -{ - return m_vimExemptionKeys; -} - -inline QList VConfigManager::getThemes() const -{ - return m_themes.keys(); -} - -inline const QString &VConfigManager::getTheme() const -{ - return m_theme; -} - -inline void VConfigManager::setTheme(const QString &p_theme) -{ - if (p_theme == m_theme) { - return; - } - - m_theme = p_theme; - setConfigToSettings("global", "theme", m_theme); - setConfigToSettings("global", "editor_style", ""); - setConfigToSettings("global", "css_style", ""); - setConfigToSettings("global", "code_block_css_style", ""); -} - -inline QList VConfigManager::getEditorStyles() const -{ - return m_editorStyles.keys(); -} - -inline const QString &VConfigManager::getEditorStyle() const -{ - return m_editorStyle; -} - -inline void VConfigManager::setEditorStyle(const QString &p_style) -{ - if (m_editorStyle == p_style) { - return; - } - - m_editorStyle = p_style; - setConfigToSettings("global", "editor_style", m_editorStyle); - updateEditStyle(); -} - -inline QList VConfigManager::getCssStyles() const -{ - return m_cssStyles.keys(); -} - -inline const QString &VConfigManager::getCssStyle() const -{ - return m_cssStyle; -} - -inline void VConfigManager::setCssStyle(const QString &p_style) -{ - if (m_cssStyle == p_style) { - return; - } - - m_cssStyle = p_style; - setConfigToSettings("global", "css_style", m_cssStyle); -} - -inline QList VConfigManager::getCodeBlockCssStyles() const -{ - return m_codeBlockCssStyles.keys(); -} - -inline const QString &VConfigManager::getCodeBlockCssStyle() const -{ - return m_codeBlockCssStyle; -} - -inline void VConfigManager::setCodeBlockCssStyle(const QString &p_style) -{ - if (m_codeBlockCssStyle == p_style) { - return; - } - - m_codeBlockCssStyle = p_style; - setConfigToSettings("global", "code_block_css_style", m_codeBlockCssStyle); -} - -#endif // VCONFIGMANAGER_H diff --git a/src/vconstants.h b/src/vconstants.h deleted file mode 100644 index 26ca8ccf..00000000 --- a/src/vconstants.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef VCONSTANTS_H -#define VCONSTANTS_H - -#include - -// Html: rich text file; -// Markdown: Markdown text file; -// List: Infinite list file like WorkFlowy; -// Container: a composite file containing multiple files; -enum class DocType { Html = 0, Markdown, List, Container, Unknown }; - -// Note: note file managed by VNote; -// Orphan: external file; -enum class FileType { Note, Orphan }; - -enum class ClipboardOpType { CopyFile, CopyDir, Invalid }; - -namespace ClipboardConfig -{ - static const QString c_type = "type"; - static const QString c_magic = "magic"; - static const QString c_isCut = "is_cut"; - static const QString c_files = "files"; - static const QString c_dirs = "dirs"; -} - -enum class OpenFileMode {Read = 0, Edit, Invalid }; - -static const qreal c_webZoomFactorMax = 5; -static const qreal c_webZoomFactorMin = 0.25; - -static const int c_tabSequenceBase = 1; - -// HTML and JS. -static const QString c_htmlJSHolder = "JS_PLACE_HOLDER"; -static const QString c_htmlExtraHolder = ""; - -// Directory Config file items. -namespace DirConfig -{ - static const QString c_version = "version"; - static const QString c_subDirectories = "sub_directories"; - static const QString c_files = "files"; - static const QString c_attachments = "attachments"; - static const QString c_imageFolder = "image_folder"; - static const QString c_attachmentFolder = "attachment_folder"; - static const QString c_recycleBinFolder = "recycle_bin_folder"; - static const QString c_name = "name"; - static const QString c_createdTime = "created_time"; - static const QString c_modifiedTime = "modified_time"; -} - -// Snippet Cofnig file items. -namespace SnippetConfig -{ - static const QString c_version = "version"; - static const QString c_snippets = "snippets"; - static const QString c_name = "name"; - static const QString c_type = "type"; - static const QString c_cursorMark = "cursor_mark"; - static const QString c_selectionMark = "selection_mark"; - static const QString c_shortcut = "shortcut"; - static const QString c_autoIndent = "auto_indent"; -} - -static const QString c_emptyHeaderName = "[EMPTY]"; - -enum class TextDecoration -{ - None, - Bold, - Italic, - Underline, - Strikethrough, - InlineCode, - CodeBlock, - Heading -}; - -enum FindOption -{ - CaseSensitive = 0x1U, - WholeWordOnly = 0x2U, - RegularExpression = 0x4U, - IncrementalSearch = 0x8U -}; - -enum class ImageProperty {/* ID of the image preview (long long). Unique for each source. */ - ImageID = 1, - /* Source type of the preview, such as image, codeblock. */ - ImageSource, - /* Type of the preview, block or inline. */ - ImageType }; - -enum class PreviewImageType { Block, Inline, Invalid }; - -enum class PreviewImageSource { Image, CodeBlock, Invalid }; - -enum HighlightBlockState -{ - Normal = 0, - - // A fenced code block. - CodeBlockStart, - CodeBlock, - CodeBlockEnd, - - // This block is inside a HTML comment region. - Comment -}; - -// Pages to open on start up. -enum class StartupPageType -{ - None = 0, - ContinueLeftOff = 1, - SpecificPages = 2, - Invalid -}; - -// Cursor block mode. -enum class CursorBlock -{ - None = 0, - // Display a cursor block on the character on the right side of the cursor. - RightSide, - // Display a cursor block on the character on the left side of the cursor. - LeftSide -}; - -enum class UpdateAction -{ - // The info of a file/directory has been changed. - InfoChanged = 0, - - // The file/directory has been moved. - Moved -}; - -#endif diff --git a/src/vdirectory.cpp b/src/vdirectory.cpp deleted file mode 100644 index 563f06a1..00000000 --- a/src/vdirectory.cpp +++ /dev/null @@ -1,718 +0,0 @@ -#include "vdirectory.h" -#include -#include -#include -#include -#include "vconfigmanager.h" -#include "vnotefile.h" -#include "utils/vutils.h" - -extern VConfigManager *g_config; - -VDirectory::VDirectory(VNotebook *p_notebook, - VDirectory *p_parent, - const QString &p_name, - QDateTime p_createdTimeUtc) - : QObject(p_parent), - m_notebook(p_notebook), - m_name(p_name), - m_opened(false), - m_expanded(false), - m_createdTimeUtc(p_createdTimeUtc) -{ -} - -bool VDirectory::open() -{ - if (m_opened) { - return true; - } - - V_ASSERT(m_subDirs.isEmpty() && m_files.isEmpty()); - - QString path = fetchPath(); - QJsonObject configJson = VConfigManager::readDirectoryConfig(path); - if (configJson.isEmpty()) { - qWarning() << "invalid directory configuration in path" << path; - return false; - } - - // created_time - m_createdTimeUtc = QDateTime::fromString(configJson[DirConfig::c_createdTime].toString(), - Qt::ISODate); - - // [sub_directories] section - QJsonArray dirJson = configJson[DirConfig::c_subDirectories].toArray(); - for (int i = 0; i < dirJson.size(); ++i) { - QJsonObject dirItem = dirJson[i].toObject(); - VDirectory *dir = new VDirectory(m_notebook, this, dirItem[DirConfig::c_name].toString()); - m_subDirs.append(dir); - } - - // [files] section - QJsonArray fileJson = configJson[DirConfig::c_files].toArray(); - for (int i = 0; i < fileJson.size(); ++i) { - QJsonObject fileItem = fileJson[i].toObject(); - VNoteFile *file = VNoteFile::fromJson(this, - fileItem, - FileType::Note, - true); - m_files.append(file); - } - - m_opened = true; - return true; -} - -void VDirectory::close() -{ - if (!m_opened) { - return; - } - - for (int i = 0; i < m_subDirs.size(); ++i) { - VDirectory *dir = m_subDirs[i]; - dir->close(); - delete dir; - } - m_subDirs.clear(); - - for (int i = 0; i < m_files.size(); ++i) { - VNoteFile *file = m_files[i]; - file->close(); - delete file; - } - m_files.clear(); - - m_opened = false; -} - -QString VDirectory::fetchBasePath() const -{ - return VUtils::basePathFromPath(fetchPath()); -} - -QString VDirectory::fetchPath(const VDirectory *p_dir) const -{ - if (!p_dir) { - return ""; - } - VDirectory *parentDir = (VDirectory *)p_dir->parent(); - if (parentDir) { - // Not the root directory - return QDir(fetchPath(parentDir)).filePath(p_dir->getName()); - } else { - return m_notebook->getPath(); - } -} - -QString VDirectory::fetchRelativePath(const VDirectory *p_dir) const -{ - if (!p_dir) { - return ""; - } - VDirectory *parentDir = (VDirectory *)p_dir->parent(); - if (parentDir) { - // Not the root directory - return QDir(fetchRelativePath(parentDir)).filePath(p_dir->getName()); - } else { - return ""; - } -} - -QJsonObject VDirectory::toConfigJson() const -{ - QJsonObject dirJson; - dirJson[DirConfig::c_version] = "1"; - dirJson[DirConfig::c_createdTime] = m_createdTimeUtc.toString(Qt::ISODate); - - QJsonArray subDirs; - for (int i = 0; i < m_subDirs.size(); ++i) { - QJsonObject item; - item[DirConfig::c_name] = m_subDirs[i]->getName(); - - subDirs.append(item); - } - dirJson[DirConfig::c_subDirectories] = subDirs; - - QJsonArray files; - for (int i = 0; i < m_files.size(); ++i) { - files.append(m_files[i]->toConfigJson()); - } - - dirJson[DirConfig::c_files] = files; - - return dirJson; -} - -bool VDirectory::readConfig() -{ - return true; -} - -bool VDirectory::writeToConfig() const -{ - QJsonObject json = toConfigJson(); - - if (!getParentDirectory()) { - // Root directory. - addNotebookConfig(json); - } - - qDebug() << "folder" << m_name << "write to config" << json; - return writeToConfig(json); -} - -bool VDirectory::updateFileConfig(const VNoteFile *p_file) -{ - Q_ASSERT(m_opened); - Q_UNUSED(p_file); - return writeToConfig(); -} - -bool VDirectory::writeToConfig(const QJsonObject &p_json) const -{ - return VConfigManager::writeDirectoryConfig(fetchPath(), p_json); -} - -void VDirectory::addNotebookConfig(QJsonObject &p_json) const -{ - V_ASSERT(!getParentDirectory()); - - QJsonObject nbJson = m_notebook->toConfigJsonNotebook(); - - // Merge it to p_json. - for (auto it = nbJson.begin(); it != nbJson.end(); ++it) { - V_ASSERT(!p_json.contains(it.key())); - p_json[it.key()] = it.value(); - } -} - -VDirectory *VDirectory::createSubDirectory(const QString &p_name, - QString *p_errMsg) -{ - Q_ASSERT(!p_name.isEmpty()); - - if (!open()) { - VUtils::addErrMsg(p_errMsg, tr("Fail to open folder %1.").arg(m_name)); - return NULL; - } - - QDir dir(fetchPath()); - if (dir.exists(p_name)) { - VUtils::addErrMsg(p_errMsg, tr("%1 already exists in directory %2.") - .arg(p_name) - .arg(fetchPath())); - return NULL; - } - - if (!dir.mkdir(p_name)) { - VUtils::addErrMsg(p_errMsg, tr("Fail to create folder in %1.") - .arg(m_name)); - return NULL; - } - - VDirectory *ret = new VDirectory(m_notebook, - this, - p_name, - QDateTime::currentDateTimeUtc()); - if (!ret->writeToConfig()) { - VUtils::addErrMsg(p_errMsg, tr("Fail to write configuration of folder %1.") - .arg(p_name)); - dir.rmdir(p_name); - delete ret; - return NULL; - } - - m_subDirs.append(ret); - if (!writeToConfig()) { - VUtils::addErrMsg(p_errMsg, tr("Fail to write configuration of folder %1.") - .arg(p_name)); - - QDir subdir(dir.filePath(p_name)); - subdir.removeRecursively(); - delete ret; - m_subDirs.removeLast(); - return NULL; - } - - return ret; -} - -VDirectory *VDirectory::findSubDirectory(const QString &p_name, bool p_caseSensitive) -{ - if (!open()) { - return NULL; - } - - QString name = p_caseSensitive ? p_name : p_name.toLower(); - for (int i = 0; i < m_subDirs.size(); ++i) { - if (name == (p_caseSensitive ? m_subDirs[i]->getName() : m_subDirs[i]->getName().toLower())) { - return m_subDirs[i]; - } - } - - return NULL; -} - -VNoteFile *VDirectory::findFile(const QString &p_name, bool p_caseSensitive) -{ - if (!open()) { - return NULL; - } - - QString name = p_caseSensitive ? p_name : p_name.toLower(); - for (int i = 0; i < m_files.size(); ++i) { - if (name == (p_caseSensitive ? m_files[i]->getName() : m_files[i]->getName().toLower())) { - return m_files[i]; - } - } - - return NULL; -} - -bool VDirectory::containsFile(const VFile *p_file) const -{ - if (!p_file) { - return false; - } - - QObject *paDir = p_file->parent(); - while (paDir) { - if (paDir == this) { - return true; - } else { - paDir = paDir->parent(); - } - } - - return false; -} - -VNoteFile *VDirectory::createFile(const QString &p_name) -{ - Q_ASSERT(!p_name.isEmpty()); - if (!open()) { - return NULL; - } - - QString path = fetchPath(); - QFile file(QDir(path).filePath(p_name)); - if (!file.open(QIODevice::WriteOnly)) { - qWarning() << "fail to create file" << p_name; - return NULL; - } - - file.close(); - - QDateTime dateTime = QDateTime::currentDateTimeUtc(); - VNoteFile *ret = new VNoteFile(this, - p_name, - FileType::Note, - true, - dateTime, - dateTime); - m_files.append(ret); - if (!writeToConfig()) { - file.remove(); - delete ret; - m_files.removeLast(); - return NULL; - } - - qDebug() << "note" << p_name << "created in folder" << m_name; - - return ret; -} - -bool VDirectory::addFile(VNoteFile *p_file, int p_index) -{ - if (!open()) { - return false; - } - - if (p_index == -1) { - m_files.append(p_file); - } else { - m_files.insert(p_index, p_file); - } - - if (!writeToConfig()) { - if (p_index == -1) { - m_files.removeLast(); - } else { - m_files.remove(p_index); - } - - return false; - } - - p_file->setParent(this); - - qDebug() << "note" << p_file->getName() << "added to folder" << m_name; - - return true; -} - -VNoteFile *VDirectory::addFile(const QString &p_name, int p_index) -{ - if (!open() || p_name.isEmpty()) { - return NULL; - } - - QDateTime dateTime = QDateTime::currentDateTimeUtc(); - VNoteFile *file = new VNoteFile(this, - p_name, - FileType::Note, - true, - dateTime, - dateTime); - if (!file) { - return NULL; - } - - if (!addFile(file, p_index)) { - delete file; - return NULL; - } - - return file; -} - -bool VDirectory::addSubDirectory(VDirectory *p_dir, int p_index) -{ - if (!open()) { - return false; - } - - if (p_index == -1) { - m_subDirs.append(p_dir); - } else { - m_subDirs.insert(p_index, p_dir); - } - - if (!writeToConfig()) { - if (p_index == -1) { - m_subDirs.removeLast(); - } else { - m_subDirs.remove(p_index); - } - - return false; - } - - p_dir->setParent(this); - - qDebug() << "folder" << p_dir->getName() << "added to folder" << m_name; - - return true; -} - -VDirectory *VDirectory::addSubDirectory(const QString &p_name, int p_index) -{ - if (!open() || p_name.isEmpty()) { - return NULL; - } - - VDirectory *dir = new VDirectory(m_notebook, - this, - p_name, - QDateTime::currentDateTimeUtc()); - if (!dir) { - return NULL; - } - - if (!addSubDirectory(dir, p_index)) { - delete dir; - return NULL; - } - - return dir; -} - -bool VDirectory::deleteDirectory(bool p_skipRecycleBin, QString *p_errMsg) -{ - Q_ASSERT(!m_opened); - Q_ASSERT(parent()); - - // Delete the entire directory. - bool ret = true; - QString dirPath = fetchPath(); - if (!VUtils::deleteDirectory(m_notebook, dirPath, p_skipRecycleBin)) { - VUtils::addErrMsg(p_errMsg, tr("Fail to delete the directory %1.").arg(dirPath)); - ret = false; - } - - return ret; -} - -bool VDirectory::deleteDirectory(VDirectory *p_dir, bool p_skipRecycleBin, QString *p_errMsg) -{ - p_dir->close(); - - bool ret = true; - - QString name = p_dir->getName(); - QString path = p_dir->fetchPath(); - - if (!p_dir->deleteDirectory(p_skipRecycleBin, p_errMsg)) { - ret = false; - } - - VDirectory *paDir = p_dir->getParentDirectory(); - Q_ASSERT(paDir); - if (!paDir->removeSubDirectory(p_dir)) { - VUtils::addErrMsg(p_errMsg, tr("Fail to remove the folder from the folder configuration.")); - ret = false; - } - - delete p_dir; - - return ret; -} - -bool VDirectory::removeSubDirectory(VDirectory *p_dir) -{ - V_ASSERT(m_opened); - V_ASSERT(p_dir); - - int index = m_subDirs.indexOf(p_dir); - V_ASSERT(index != -1); - m_subDirs.remove(index); - - if (!writeToConfig()) { - return false; - } - - return true; -} - -bool VDirectory::removeFile(VNoteFile *p_file) -{ - V_ASSERT(m_opened); - V_ASSERT(p_file); - - int index = m_files.indexOf(p_file); - V_ASSERT(index != -1); - m_files.remove(index); - - if (!writeToConfig()) { - return false; - } - - return true; -} - -bool VDirectory::rename(const QString &p_name) -{ - if (m_name == p_name) { - return true; - } - - QString oldName = m_name; - - VDirectory *parentDir = getParentDirectory(); - V_ASSERT(parentDir); - // Rename it in disk. - QDir dir(parentDir->fetchPath()); - if (!dir.rename(m_name, p_name)) { - qWarning() << "fail to rename folder" << m_name << "to" << p_name << "in disk"; - return false; - } - - m_name = p_name; - - // Update parent's config file - if (!parentDir->writeToConfig()) { - m_name = oldName; - dir.rename(p_name, m_name); - return false; - } - - qDebug() << "folder renamed from" << oldName << "to" << m_name; - - return true; -} - -bool VDirectory::copyDirectory(VDirectory *p_destDir, - const QString &p_destName, - VDirectory *p_dir, - bool p_isCut, - VDirectory **p_targetDir, - QString *p_errMsg) -{ - bool ret = true; - *p_targetDir = NULL; - - QString srcPath = QDir::cleanPath(p_dir->fetchPath()); - QString destPath = QDir::cleanPath(QDir(p_destDir->fetchPath()).filePath(p_destName)); - if (VUtils::equalPath(srcPath, destPath)) { - *p_targetDir = p_dir; - return false; - } - - if (!p_destDir->isOpened()) { - VUtils::addErrMsg(p_errMsg, tr("Fail to open target folder.")); - return false; - } - - QString opStr = p_isCut ? tr("cut") : tr("copy"); - VDirectory *paDir = p_dir->getParentDirectory(); - - Q_ASSERT(paDir->isOpened()); - - // Copy the directory. - if (!VUtils::copyDirectory(srcPath, destPath, p_isCut)) { - VUtils::addErrMsg(p_errMsg, tr("Fail to %1 the folder.").arg(opStr)); - qWarning() << "fail to" << opStr << "the folder directory" << srcPath << "to" << destPath; - return false; - } - - // Add directory to VDirectory. - VDirectory *destDir = NULL; - if (p_isCut) { - paDir->removeSubDirectory(p_dir); - p_dir->setName(p_destName); - // Add the directory to new dir's config - if (p_destDir->addSubDirectory(p_dir, -1)) { - destDir = p_dir; - } else { - destDir = NULL; - } - } else { - destDir = p_destDir->addSubDirectory(p_destName, -1); - } - - if (!destDir) { - VUtils::addErrMsg(p_errMsg, tr("Fail to add the folder to target folder's configuration.")); - return false; - } - - qDebug() << "copyDirectory:" << p_dir << "to" << destDir; - - *p_targetDir = destDir; - return ret; -} - -void VDirectory::setExpanded(bool p_expanded) -{ - if (p_expanded) { - V_ASSERT(m_opened); - } - - m_expanded = p_expanded; -} - -VNoteFile *VDirectory::tryLoadFile(QStringList &p_filePath) -{ - qDebug() << "directory" << m_name << "tryLoadFile()" << p_filePath.join("/"); - if (p_filePath.isEmpty()) { - return NULL; - } - - bool opened = isOpened(); - if (!open()) { - return NULL; - } - - VNoteFile *file = NULL; - -#if defined(Q_OS_WIN) - bool caseSensitive = false; -#else - bool caseSensitive = true; -#endif - - if (p_filePath.size() == 1) { - // File. - file = findFile(p_filePath.at(0), caseSensitive); - } else { - // Directory. - VDirectory *dir = findSubDirectory(p_filePath.at(0), caseSensitive); - if (dir) { - p_filePath.removeFirst(); - file = dir->tryLoadFile(p_filePath); - } - } - - if (!file && !opened) { - close(); - } - - return file; -} - -VDirectory *VDirectory::tryLoadDirectory(QStringList &p_filePath) -{ - qDebug() << "directory" << m_name << "tryLoadDirectory()" << p_filePath.join("/"); - if (p_filePath.isEmpty()) { - return NULL; - } - - bool opened = isOpened(); - if (!open()) { - return NULL; - } - -#if defined(Q_OS_WIN) - bool caseSensitive = false; -#else - bool caseSensitive = true; -#endif - - VDirectory *dir = findSubDirectory(p_filePath.at(0), caseSensitive); - if (dir) { - if (p_filePath.size() > 1) { - p_filePath.removeFirst(); - dir = dir->tryLoadDirectory(p_filePath); - } - } - - if (!dir && !opened) { - close(); - } - - return dir; -} - -bool VDirectory::sortFiles(const QVector &p_sortedIdx) -{ - V_ASSERT(m_opened); - V_ASSERT(p_sortedIdx.size() == m_files.size()); - - auto ori = m_files; - - for (int i = 0; i < p_sortedIdx.size(); ++i) { - m_files[i] = ori[p_sortedIdx[i]]; - } - - bool ret = true; - if (!writeToConfig()) { - qWarning() << "fail to reorder files in config" << p_sortedIdx; - m_files = ori; - ret = false; - } - - return ret; -} - -bool VDirectory::sortSubDirectories(const QVector &p_sortedIdx) -{ - V_ASSERT(m_opened); - V_ASSERT(p_sortedIdx.size() == m_subDirs.size()); - - auto ori = m_subDirs; - - for (int i = 0; i < p_sortedIdx.size(); ++i) { - m_subDirs[i] = ori[p_sortedIdx[i]]; - } - - bool ret = true; - if (!writeToConfig()) { - qWarning() << "fail to reorder sub-directories in config" << p_sortedIdx; - m_subDirs = ori; - ret = false; - } - - return ret; -} diff --git a/src/vdirectory.h b/src/vdirectory.h deleted file mode 100644 index 6d1983e3..00000000 --- a/src/vdirectory.h +++ /dev/null @@ -1,238 +0,0 @@ -#ifndef VDIRECTORY_H -#define VDIRECTORY_H - -#include -#include -#include -#include -#include -#include -#include "vnotebook.h" - -class VFile; -class VNoteFile; - -class VDirectory : public QObject -{ - Q_OBJECT -public: - VDirectory(VNotebook *p_notebook, - VDirectory *p_parent, - const QString &p_name, - QDateTime p_createdTimeUtc = QDateTime()); - - bool open(); - void close(); - - // Create a sub-directory with name @p_name. - VDirectory *createSubDirectory(const QString &p_name, - QString *p_errMsg = NULL); - - // Returns the VDirectory with the name @p_name directly in this directory. - VDirectory *findSubDirectory(const QString &p_name, bool p_caseSensitive); - - // Returns the VNoteFile with the name @p_name directly in this directory. - VNoteFile *findFile(const QString &p_name, bool p_caseSensitive); - - // If current dir or its sub-dir contains @p_file. - bool containsFile(const VFile *p_file) const; - - VNoteFile *createFile(const QString &p_name); - - // Remove the file in the config and m_files without deleting it in the disk. - // It won't change the parent of @p_file to enable it find its path. - bool removeFile(VNoteFile *p_file); - - // Remove the directory in the config and m_subDirs without deleting it in the disk. - // It won't change the parent of @p_dir to enable it find its path. - bool removeSubDirectory(VDirectory *p_dir); - - // Add the file in the config and m_files. If @p_index is -1, add it at the end. - // @p_name: the file name of the file to add. - // Return the VNoteFile if succeed. - VNoteFile *addFile(const QString &p_name, int p_index); - - // Add the file in the config and m_files. If @p_index is -1, add it at the end. - bool addFile(VNoteFile *p_file, int p_index); - - // Rename current directory to @p_name. - bool rename(const QString &p_name); - - // Copy @p_dir as a sub-directory of @p_destDir with the new name @p_destName. - // Return a directory representing the destination directory after copy/cut. - static bool copyDirectory(VDirectory *p_destDir, - const QString &p_destName, - VDirectory *p_dir, - bool p_isCut, - VDirectory **p_targetDir, - QString *p_errMsg = NULL); - - const QVector &getSubDirs() const; - - const QString &getName() const; - void setName(const QString &p_name); - bool isOpened() const; - VDirectory *getParentDirectory(); - const VDirectory *getParentDirectory() const; - VNotebook *getNotebook(); - const VNotebook *getNotebook() const; - const QVector &getFiles() const; - QString fetchPath() const; - QString fetchBasePath() const; - QString fetchRelativePath() const; - QString getNotebookName() const; - bool isExpanded() const; - void setExpanded(bool p_expanded); - - // Serialize current instance to json. - // Not including sections belonging to notebook. - QJsonObject toConfigJson() const; - - // Read configurations (excluding "sub_directories" and "files" section) - // from config file. - bool readConfig(); - - // Write current instance to config file. - // If it is root directory, this will include sections belonging to - // notebook. - bool writeToConfig() const; - - // Write the config of @p_file to config file. - bool updateFileConfig(const VNoteFile *p_file); - - // Try to load file given relative path @p_filePath. - VNoteFile *tryLoadFile(QStringList &p_filePath); - - // Try to load directory given relative path @p_filePath. - VDirectory *tryLoadDirectory(QStringList &p_filePath); - - QDateTime getCreatedTimeUtc() const; - - // Reorder files in m_files by index. - bool sortFiles(const QVector &p_sortedIdx); - - // Reorder sub-directories in m_subDirs by index. - bool sortSubDirectories(const QVector &p_sortedIdx); - - // Delete directory @p_dir. - static bool deleteDirectory(VDirectory *p_dir, - bool p_skipRecycleBin = false, - QString *p_errMsg = NULL); - -private: - // Get the path of @p_dir recursively - QString fetchPath(const VDirectory *p_dir) const; - // Get teh relative path of @p_dir recursively related to the notebook path - QString fetchRelativePath(const VDirectory *p_dir) const; - - // Write @p_json to config. - bool writeToConfig(const QJsonObject &p_json) const; - - // Add notebook part config to @p_json. - // Should only be called with root directory. - void addNotebookConfig(QJsonObject &p_json) const; - - // Add the directory in the config and m_subDirs. If @p_index is -1, add it at the end. - // Return the VDirectory if succeed. - VDirectory *addSubDirectory(const QString &p_name, int p_index); - - // Add the directory in the config and m_subDirs. If @p_index is -1, add it at the end. - bool addSubDirectory(VDirectory *p_dir, int p_index); - - // Delete this directory in disk. - bool deleteDirectory(bool p_skipRecycleBin = false, QString *p_errMsg = NULL); - - // Notebook containing this folder. - QPointer m_notebook; - - // Name of this folder. - QString m_name; - - // Owner of the sub-directories - QVector m_subDirs; - - // Owner of the files - QVector m_files; - - // Whether the directory has been opened. - bool m_opened; - - // Whether expanded in the directory tree. - bool m_expanded; - - // UTC time when creating this directory. - // Loaded after open(). - QDateTime m_createdTimeUtc; -}; - -inline const QVector &VDirectory::getSubDirs() const -{ - return m_subDirs; -} - -inline const QString &VDirectory::getName() const -{ - return m_name; -} - -inline void VDirectory::setName(const QString &p_name) -{ - m_name = p_name; -} - -inline bool VDirectory::isOpened() const -{ - return m_opened; -} - -inline VDirectory *VDirectory::getParentDirectory() -{ - return (VDirectory *)this->parent(); -} - -inline const VDirectory *VDirectory::getParentDirectory() const -{ - return (const VDirectory *)this->parent(); -} - -inline const QVector &VDirectory::getFiles() const -{ - return m_files; -} - -inline QString VDirectory::getNotebookName() const -{ - return m_notebook->getName(); -} - -inline VNotebook *VDirectory::getNotebook() -{ - return m_notebook; -} - -inline const VNotebook *VDirectory::getNotebook() const -{ - return m_notebook; -} - -inline QString VDirectory::fetchPath() const -{ - return fetchPath(this); -} - -inline QString VDirectory::fetchRelativePath() const -{ - return fetchRelativePath(this); -} - -inline bool VDirectory::isExpanded() const -{ - return m_expanded; -} - -inline QDateTime VDirectory::getCreatedTimeUtc() const -{ - return m_createdTimeUtc; -} - -#endif // VDIRECTORY_H diff --git a/src/vdirectorytree.cpp b/src/vdirectorytree.cpp deleted file mode 100644 index b460f0be..00000000 --- a/src/vdirectorytree.cpp +++ /dev/null @@ -1,1182 +0,0 @@ -#include -#include "vdirectorytree.h" -#include "dialog/vnewdirdialog.h" -#include "vconfigmanager.h" -#include "dialog/vdirinfodialog.h" -#include "vnote.h" -#include "vdirectory.h" -#include "utils/vutils.h" -#include "veditarea.h" -#include "vconfigmanager.h" -#include "vmainwindow.h" -#include "dialog/vsortdialog.h" -#include "utils/vimnavigationforwidget.h" -#include "utils/viconutils.h" - -extern VMainWindow *g_mainWin; - -extern VConfigManager *g_config; -extern VNote *g_vnote; - -const QString VDirectoryTree::c_infoShortcutSequence = "F2"; -const QString VDirectoryTree::c_copyShortcutSequence = "Ctrl+C"; -const QString VDirectoryTree::c_cutShortcutSequence = "Ctrl+X"; -const QString VDirectoryTree::c_pasteShortcutSequence = "Ctrl+V"; - -VDirectoryTree::VDirectoryTree(QWidget *parent) - : QTreeWidget(parent), VNavigationMode(), - m_editArea(NULL) -{ - setColumnCount(1); - setHeaderHidden(true); - setContextMenuPolicy(Qt::CustomContextMenu); - setAttribute(Qt::WA_MacShowFocusRect, false); - - initShortcuts(); - initActions(); - - connect(this, SIGNAL(itemExpanded(QTreeWidgetItem*)), - this, SLOT(handleItemExpanded(QTreeWidgetItem*))); - connect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), - this, SLOT(handleItemCollapsed(QTreeWidgetItem*))); - connect(this, SIGNAL(customContextMenuRequested(QPoint)), - this, SLOT(contextMenuRequested(QPoint))); - connect(this, &VDirectoryTree::currentItemChanged, - this, &VDirectoryTree::currentDirectoryItemChanged); -} - -void VDirectoryTree::initShortcuts() -{ - QShortcut *infoShortcut = new QShortcut(QKeySequence(c_infoShortcutSequence), this); - infoShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(infoShortcut, &QShortcut::activated, - this, [this](){ - editDirectoryInfo(); - }); - - QShortcut *copyShortcut = new QShortcut(QKeySequence(c_copyShortcutSequence), this); - copyShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(copyShortcut, &QShortcut::activated, - this, [this](){ - copySelectedDirectories(); - }); - - QShortcut *cutShortcut = new QShortcut(QKeySequence(c_cutShortcutSequence), this); - cutShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(cutShortcut, &QShortcut::activated, - this, [this](){ - cutSelectedDirectories(); - }); - - QShortcut *pasteShortcut = new QShortcut(QKeySequence(c_pasteShortcutSequence), this); - pasteShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(pasteShortcut, &QShortcut::activated, - this, [this](){ - pasteDirectoriesFromClipboard(); - }); -} - -void VDirectoryTree::initActions() -{ - newRootDirAct = new QAction(VIconUtils::menuIcon(":/resources/icons/create_rootdir.svg"), - tr("New &Root Folder"), this); - newRootDirAct->setToolTip(tr("Create a root folder in current notebook")); - connect(newRootDirAct, &QAction::triggered, - this, &VDirectoryTree::newRootDirectory); - - newSubDirAct = new QAction(VIconUtils::menuIcon(":/resources/icons/create_subdir.svg"), - tr("&New Subfolder"), this); - newSubDirAct->setToolTip(tr("Create a subfolder")); - connect(newSubDirAct, &QAction::triggered, - this, &VDirectoryTree::newSubDirectory); - - deleteDirAct = new QAction(VIconUtils::menuDangerIcon(":/resources/icons/delete_dir.svg"), - tr("&Delete"), this); - deleteDirAct->setToolTip(tr("Delete selected folder")); - connect(deleteDirAct, &QAction::triggered, - this, &VDirectoryTree::deleteSelectedDirectory); - - dirInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/dir_info.svg"), - tr("&Info\t%1").arg(VUtils::getShortcutText(c_infoShortcutSequence)), this); - dirInfoAct->setToolTip(tr("View and edit current folder's information")); - connect(dirInfoAct, &QAction::triggered, - this, &VDirectoryTree::editDirectoryInfo); - - copyAct = new QAction(VIconUtils::menuIcon(":/resources/icons/copy.svg"), - tr("&Copy\t%1").arg(VUtils::getShortcutText(c_copyShortcutSequence)), this); - copyAct->setToolTip(tr("Copy selected folders")); - connect(copyAct, &QAction::triggered, - this, &VDirectoryTree::copySelectedDirectories); - - cutAct = new QAction(VIconUtils::menuIcon(":/resources/icons/cut.svg"), - tr("C&ut\t%1").arg(VUtils::getShortcutText(c_cutShortcutSequence)), this); - cutAct->setToolTip(tr("Cut selected folders")); - connect(cutAct, &QAction::triggered, - this, &VDirectoryTree::cutSelectedDirectories); - - pasteAct = new QAction(VIconUtils::menuIcon(":/resources/icons/paste.svg"), - tr("&Paste\t%1").arg(VUtils::getShortcutText(c_pasteShortcutSequence)), this); - pasteAct->setToolTip(tr("Paste folders in this folder")); - connect(pasteAct, &QAction::triggered, - this, &VDirectoryTree::pasteDirectoriesFromClipboard); - - m_openLocationAct = new QAction(tr("&Open Folder Location"), this); - m_openLocationAct->setToolTip(tr("Open the folder containing this folder in operating system")); - connect(m_openLocationAct, &QAction::triggered, - this, &VDirectoryTree::openDirectoryLocation); - - m_reloadAct = new QAction(tr("&Reload From Disk"), this); - m_reloadAct->setToolTip(tr("Reload the content of this folder (or notebook) from disk")); - connect(m_reloadAct, &QAction::triggered, - this, &VDirectoryTree::reloadFromDisk); - - m_sortAct = new QAction(VIconUtils::menuIcon(":/resources/icons/sort.svg"), - tr("&Sort"), - this); - m_sortAct->setToolTip(tr("Sort folders in this folder/notebook manually")); - connect(m_sortAct, SIGNAL(triggered(bool)), - this, SLOT(sortItems())); -} - -void VDirectoryTree::setNotebook(VNotebook *p_notebook) -{ - if (m_notebook == p_notebook) { - return; - } - - clear(); - m_notebook = p_notebook; - if (!m_notebook) { - return; - } - - if (!m_notebook->open()) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to open notebook %2.") - .arg(g_config->c_dataTextStyle) - .arg(m_notebook->getName()), - tr("Please check if the notebook's root folder %2 exists.") - .arg(g_config->c_dataTextStyle) - .arg(m_notebook->getPath()), - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - updateDirectoryTree(); -} - -void VDirectoryTree::fillTreeItem(QTreeWidgetItem *p_item, VDirectory *p_directory) -{ - int col = 0; - QString name = p_directory->getName(); - p_item->setText(col, name); - p_item->setToolTip(col, name); - p_item->setData(col, Qt::UserRole, QVariant::fromValue(p_directory)); - p_item->setIcon(col, VIconUtils::treeViewIcon(":/resources/icons/dir_item.svg")); -} - -void VDirectoryTree::updateDirectoryTree() -{ - clear(); - - VDirectory *rootDir = m_notebook->getRootDir(); - const QVector &subDirs = rootDir->getSubDirs(); - for (int i = 0; i < subDirs.size(); ++i) { - VDirectory *dir = subDirs[i]; - QTreeWidgetItem *item = new QTreeWidgetItem(this); - - fillTreeItem(item, dir); - - buildSubTree(item, 1); - } - - if (!restoreCurrentItem() && topLevelItemCount() > 0) { - setCurrentItem(topLevelItem(0)); - } -} - -bool VDirectoryTree::restoreCurrentItem() -{ - auto it = m_notebookCurrentDirMap.find(m_notebook); - if (it != m_notebookCurrentDirMap.end()) { - QTreeWidgetItem *item = findVDirectory(it.value()); - if (item) { - setCurrentItem(item); - return true; - } - } - - return false; -} - -void VDirectoryTree::buildSubTree(QTreeWidgetItem *p_parent, int p_depth) -{ - if (p_depth == 0) { - return; - } - - Q_ASSERT(p_parent); - - VDirectory *dir = getVDirectory(p_parent); - if (!dir->open()) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to open folder %2.") - .arg(g_config->c_dataTextStyle) - .arg(dir->getName()), - tr("Please check if directory %2 exists.") - .arg(g_config->c_dataTextStyle) - .arg(dir->fetchPath()), - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - if (p_parent->childCount() > 0) { - // This directory has been built before. Try its children directly. - int cnt = p_parent->childCount(); - for (int i = 0; i < cnt; ++i) { - buildSubTree(p_parent->child(i), p_depth -1); - } - } else { - const QVector &subDirs = dir->getSubDirs(); - for (int i = 0; i < subDirs.size(); ++i) { - VDirectory *subDir = subDirs[i]; - QTreeWidgetItem *item = new QTreeWidgetItem(p_parent); - fillTreeItem(item, subDir); - buildSubTree(item, p_depth - 1); - } - } - - if (dir->isExpanded()) { - expandItem(p_parent); - } -} - -void VDirectoryTree::handleItemCollapsed(QTreeWidgetItem *p_item) -{ - if (p_item) { - VDirectory *dir = getVDirectory(p_item); - dir->setExpanded(false); - } -} - -void VDirectoryTree::handleItemExpanded(QTreeWidgetItem *p_item) -{ - if (p_item) { - buildChildren(p_item); - - VDirectory *dir = getVDirectory(p_item); - dir->setExpanded(true); - } -} - -void VDirectoryTree::buildChildren(QTreeWidgetItem *p_item) -{ - Q_ASSERT(p_item); - int nrChild = p_item->childCount(); - if (nrChild == 0) { - return; - } - - for (int i = 0; i < nrChild; ++i) { - QTreeWidgetItem *childItem = p_item->child(i); - if (childItem->childCount() > 0) { - continue; - } - - buildSubTree(childItem, 1); - } -} - -void VDirectoryTree::updateItemDirectChildren(QTreeWidgetItem *p_item) -{ - QPointer parentDir; - if (p_item) { - parentDir = getVDirectory(p_item); - } else { - parentDir = m_notebook->getRootDir(); - } - - const QVector &dirs = parentDir->getSubDirs(); - - QHash itemDirMap; - int nrChild = p_item ? p_item->childCount() : topLevelItemCount(); - for (int i = 0; i < nrChild; ++i) { - QTreeWidgetItem *item = p_item ? p_item->child(i) : topLevelItem(i); - itemDirMap.insert(getVDirectory(item), item); - } - - for (int i = 0; i < dirs.size(); ++i) { - VDirectory *dir = dirs[i]; - QTreeWidgetItem *item = itemDirMap.value(dir, NULL); - if (item) { - if (p_item) { - p_item->removeChild(item); - p_item->insertChild(i, item); - } else { - int topIdx = indexOfTopLevelItem(item); - takeTopLevelItem(topIdx); - insertTopLevelItem(i, item); - } - - itemDirMap.remove(dir); - } else { - // Insert a new item - if (p_item) { - item = new QTreeWidgetItem(p_item); - } else { - item = new QTreeWidgetItem(this); - } - - fillTreeItem(item, dir); - buildSubTree(item, 1); - } - - expandSubTree(item); - } - - // Delete items without corresponding VDirectory - for (auto iter = itemDirMap.begin(); iter != itemDirMap.end(); ++iter) { - QTreeWidgetItem *item = iter.value(); - if (p_item) { - p_item->removeChild(item); - } else { - int topIdx = indexOfTopLevelItem(item); - takeTopLevelItem(topIdx); - } - - delete item; - } -} - -void VDirectoryTree::contextMenuRequested(QPoint pos) -{ - QTreeWidgetItem *item = itemAt(pos); - - if (!m_notebook) { - return; - } - - QMenu menu(this); - menu.setToolTipsVisible(true); - - if (!item) { - // Context menu on the free space of the QTreeWidget - menu.addAction(newRootDirAct); - - if (topLevelItemCount() > 1) { - menu.addAction(m_sortAct); - } - } else { - // Context menu on a QTreeWidgetItem - if (item->parent()) { - // Low-level item - menu.addAction(newSubDirAct); - - if (item->parent()->childCount() > 1) { - menu.addAction(m_sortAct); - } - } else { - // Top-level item - menu.addAction(newRootDirAct); - menu.addAction(newSubDirAct); - - if (topLevelItemCount() > 1) { - menu.addAction(m_sortAct); - } - } - - menu.addSeparator(); - menu.addAction(deleteDirAct); - menu.addAction(copyAct); - menu.addAction(cutAct); - } - - if (pasteAvailable()) { - if (!item) { - menu.addSeparator(); - } - - menu.addAction(pasteAct); - } - - menu.addSeparator(); - menu.addAction(m_reloadAct); - - if (item) { - menu.addAction(m_openLocationAct); - menu.addAction(dirInfoAct); - } - - menu.exec(mapToGlobal(pos)); -} - -void VDirectoryTree::newSubDirectory() -{ - if (!m_notebook) { - return; - } - - QTreeWidgetItem *curItem = currentItem(); - if (!curItem) { - return; - } - - VDirectory *curDir = getVDirectory(curItem); - - QString info = tr("Create a subfolder in %2.") - .arg(g_config->c_dataTextStyle) - .arg(curDir->getName()); - QString defaultName("new_folder"); - defaultName = VUtils::getDirNameWithSequence(curDir->fetchPath(), defaultName); - VNewDirDialog dialog(tr("Create Folder"), info, defaultName, curDir, this); - if (dialog.exec() == QDialog::Accepted) { - QString name = dialog.getNameInput(); - QString msg; - VDirectory *subDir = curDir->createSubDirectory(name, &msg); - if (!subDir) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to create subfolder %2.") - .arg(g_config->c_dataTextStyle) - .arg(name), - msg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - updateItemDirectChildren(curItem); - - locateDirectory(subDir); - } -} - -void VDirectoryTree::newRootDirectory() -{ - if (!m_notebook) { - return; - } - - VDirectory *rootDir = m_notebook->getRootDir(); - - QString info = tr("Create a root folder in notebook %2.") - .arg(g_config->c_dataTextStyle) - .arg(m_notebook->getName()); - QString defaultName("new_folder"); - defaultName = VUtils::getDirNameWithSequence(rootDir->fetchPath(), defaultName); - VNewDirDialog dialog(tr("Create Root Folder"), info, defaultName, rootDir, this); - if (dialog.exec() == QDialog::Accepted) { - QString name = dialog.getNameInput(); - QString msg; - VDirectory *dir = rootDir->createSubDirectory(name, &msg); - if (!dir) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to create root folder %2.") - .arg(g_config->c_dataTextStyle) - .arg(name), - msg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - updateItemDirectChildren(NULL); - - locateDirectory(dir); - } -} - -void VDirectoryTree::deleteSelectedDirectory() -{ - Q_ASSERT(selectedItems().size() <= 1); - - QTreeWidgetItem *curItem = currentItem(); - if (!curItem) { - return; - } - - VDirectory *curDir = getVDirectory(curItem); - int ret = VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Are you sure to delete folder %2?") - .arg(g_config->c_dataTextStyle) - .arg(curDir->getName()), - tr("WARNING: " - "VNote will delete the whole directory " - "%3." - "Deleted files could be found in the recycle bin " - "of this folder.
    " - "The operation is IRREVERSIBLE!") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(curDir->fetchPath()), - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Ok, - this, - MessageBoxType::Danger); - - if (ret == QMessageBox::Ok) { - int nrDeleted = 1; - m_editArea->closeFile(curDir, true); - - // Remove the item from the tree. - delete curItem; - - QString msg; - QString dirName = curDir->getName(); - QString dirPath = curDir->fetchPath(); - if (!VDirectory::deleteDirectory(curDir, false, &msg)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to delete folder %2.
    " - "Please check %3 and manually delete it.") - .arg(g_config->c_dataTextStyle) - .arg(dirName) - .arg(dirPath), - msg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } else { - g_mainWin->showStatusMessage(tr("%1 %2 deleted") - .arg(nrDeleted) - .arg(nrDeleted > 1 ? tr("folders") : tr("folder"))); - } - } -} - -void VDirectoryTree::currentDirectoryItemChanged(QTreeWidgetItem *currentItem) -{ - if (!currentItem) { - emit currentDirectoryChanged(NULL); - return; - } - - QPointer dir = getVDirectory(currentItem); - m_notebookCurrentDirMap[m_notebook] = dir; - emit currentDirectoryChanged(dir); -} - -void VDirectoryTree::editDirectoryInfo() -{ - QTreeWidgetItem *curItem = currentItem(); - if (!curItem) { - return; - } - - VDirectory *curDir = getVDirectory(curItem); - QString curName = curDir->getName(); - - VDirInfoDialog dialog(tr("Folder Information"), - "", - curDir, - curDir->getParentDirectory(), - this); - if (dialog.exec() == QDialog::Accepted) { - QString name = dialog.getNameInput(); - if (name == curName) { - return; - } - - if (!curDir->rename(name)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to rename folder %2.") - .arg(g_config->c_dataTextStyle) - .arg(curName), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - fillTreeItem(curItem, curDir); - - emit directoryUpdated(curDir, UpdateAction::InfoChanged); - } -} - -void VDirectoryTree::openDirectoryLocation() const -{ - QTreeWidgetItem *curItem = currentItem(); - V_ASSERT(curItem); - QUrl url = QUrl::fromLocalFile(getVDirectory(curItem)->fetchBasePath()); - QDesktopServices::openUrl(url); -} - -void VDirectoryTree::reloadFromDisk() -{ - if (!m_notebook) { - return; - } - - QString msg; - QString info; - VDirectory *curDir = NULL; - QTreeWidgetItem *curItem = currentItem(); - if (curItem) { - // Reload current directory. - curDir = getVDirectory(curItem); - info = tr("Are you sure to reload folder %2?") - .arg(g_config->c_dataTextStyle).arg(curDir->getName()); - msg = tr("Folder %1 reloaded from disk").arg(curDir->getName()); - } else { - // Reload notebook. - info = tr("Are you sure to reload notebook %2?") - .arg(g_config->c_dataTextStyle).arg(m_notebook->getName()); - msg = tr("Notebook %1 reloaded from disk").arg(m_notebook->getName()); - } - - if (g_config->getConfirmReloadFolder()) { - int ret = VUtils::showMessage(QMessageBox::Information, tr("Information"), - info, - tr("VNote will close all the related notes before reload."), - QMessageBox::Ok | QMessageBox::YesToAll | QMessageBox::Cancel, - QMessageBox::Ok, - this); - switch (ret) { - case QMessageBox::YesToAll: - g_config->setConfirmReloadFolder(false); - // Fall through. - - case QMessageBox::Ok: - break; - - case QMessageBox::Cancel: - return; - - default: - return; - } - } - - m_notebookCurrentDirMap.remove(m_notebook); - - if (curItem) { - if (!m_editArea->closeFile(curDir, false)) { - return; - } - - setCurrentItem(NULL); - - curItem->setExpanded(false); - curDir->setExpanded(false); - - curDir->close(); - - // Remove all its children. - QList children = curItem->takeChildren(); - for (int i = 0; i < children.size(); ++i) { - delete children[i]; - } - - buildSubTree(curItem, 1); - - setCurrentItem(curItem); - } else { - if (!m_editArea->closeFile(m_notebook, false)) { - return; - } - - m_notebook->close(); - - if (!m_notebook->open()) { - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Fail to open notebook %2.") - .arg(g_config->c_dataTextStyle).arg(m_notebook->getName()), - tr("Please check if path %2 exists.") - .arg(g_config->c_dataTextStyle).arg(m_notebook->getPath()), - QMessageBox::Ok, QMessageBox::Ok, this); - clear(); - return; - } - - updateDirectoryTree(); - } - - if (!msg.isEmpty()) { - g_mainWin->showStatusMessage(msg); - } -} - -void VDirectoryTree::copySelectedDirectories(bool p_isCut) -{ - QList items = selectedItems(); - if (items.isEmpty()) { - return; - } - - QJsonArray dirs; - for (int i = 0; i < items.size(); ++i) { - VDirectory *dir = getVDirectory(items[i]); - dirs.append(dir->fetchPath()); - } - - QJsonObject clip; - clip[ClipboardConfig::c_magic] = getNewMagic(); - clip[ClipboardConfig::c_type] = (int)ClipboardOpType::CopyDir; - clip[ClipboardConfig::c_isCut] = p_isCut; - clip[ClipboardConfig::c_dirs] = dirs; - - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(QJsonDocument(clip).toJson(QJsonDocument::Compact)); - - qDebug() << "copied directories info" << clipboard->text(); - - int cnt = dirs.size(); - g_mainWin->showStatusMessage(tr("%1 %2 %3") - .arg(cnt) - .arg(cnt > 1 ? tr("folders") : tr("folder")) - .arg(p_isCut ? tr("cut") : tr("copied"))); -} - -void VDirectoryTree::cutSelectedDirectories() -{ - copySelectedDirectories(true); -} - -void VDirectoryTree::pasteDirectoriesFromClipboard() -{ - if (!pasteAvailable()) { - return; - } - - QJsonObject obj = VUtils::clipboardToJson(); - QJsonArray dirs = obj[ClipboardConfig::c_dirs].toArray(); - bool isCut = obj[ClipboardConfig::c_isCut].toBool(); - QVector dirsToPaste(dirs.size()); - for (int i = 0; i < dirs.size(); ++i) { - dirsToPaste[i] = dirs[i].toString(); - } - - VDirectory *destDir; - QTreeWidgetItem *item = currentItem(); - if (item) { - destDir = getVDirectory(item); - } else { - destDir = m_notebook->getRootDir(); - } - - pasteDirectories(destDir, dirsToPaste, isCut); - - QClipboard *clipboard = QApplication::clipboard(); - clipboard->clear(); -} - -void VDirectoryTree::pasteDirectories(VDirectory *p_destDir, - const QVector &p_dirs, - bool p_isCut) -{ - if (!p_destDir || p_dirs.isEmpty()) { - return; - } - - int nrPasted = 0; - for (int i = 0; i < p_dirs.size(); ++i) { - VDirectory *dir = g_vnote->getInternalDirectory(p_dirs[i]); - if (!dir) { - qWarning() << "Copied dir is not an internal folder" << p_dirs[i]; - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to paste folder %2.") - .arg(g_config->c_dataTextStyle) - .arg(p_dirs[i]), - tr("VNote could not find this folder in any notebook."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - - continue; - } - - if (dir == p_destDir) { - continue; - } - - QString dirName = dir->getName(); - VDirectory *paDir = dir->getParentDirectory(); - if (paDir == p_destDir) { - if (p_isCut) { - continue; - } - - // Copy and paste in the same folder. - // Rename it to xxx_copy. - dirName = VUtils::generateCopiedDirName(paDir->fetchPath(), dirName); - } else { - // Rename it to xxx_copy if needed. - dirName = VUtils::generateCopiedDirName(p_destDir->fetchPath(), dirName); - } - - QString msg; - VDirectory *destDir = NULL; - bool ret = VDirectory::copyDirectory(p_destDir, - dirName, - dir, - p_isCut, - &destDir, - &msg); - if (!ret) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to copy folder %2.") - .arg(g_config->c_dataTextStyle) - .arg(p_dirs[i]), - msg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - if (destDir) { - ++nrPasted; - - // Update QTreeWidget. - bool isWidget; - QTreeWidgetItem *destItem = findVDirectory(p_destDir, &isWidget); - if (destItem || isWidget) { - updateItemDirectChildren(destItem); - } - - if (p_isCut) { - QTreeWidgetItem *srcItem = findVDirectory(paDir, &isWidget); - if (srcItem || isWidget) { - updateItemDirectChildren(srcItem); - } - } - - // Broadcast this update - emit directoryUpdated(destDir, p_isCut ? UpdateAction::Moved : UpdateAction::InfoChanged); - } - } - - qDebug() << "pasted" << nrPasted << "directories"; - if (nrPasted > 0) { - g_mainWin->showStatusMessage(tr("%1 %2 pasted") - .arg(nrPasted) - .arg(nrPasted > 1 ? tr("folders") : tr("folder"))); - } - - getNewMagic(); -} - -bool VDirectoryTree::pasteAvailable() const -{ - QJsonObject obj = VUtils::clipboardToJson(); - if (obj.isEmpty()) { - return false; - } - - if (!obj.contains(ClipboardConfig::c_type)) { - return false; - } - - ClipboardOpType type = (ClipboardOpType)obj[ClipboardConfig::c_type].toInt(); - if (type != ClipboardOpType::CopyDir) { - return false; - } - - if (!obj.contains(ClipboardConfig::c_magic) - || !obj.contains(ClipboardConfig::c_isCut) - || !obj.contains(ClipboardConfig::c_dirs)) { - return false; - } - - int magic = obj[ClipboardConfig::c_magic].toInt(); - if (!checkMagic(magic)) { - return false; - } - - QJsonArray dirs = obj[ClipboardConfig::c_dirs].toArray(); - return !dirs.isEmpty(); -} - -void VDirectoryTree::mousePressEvent(QMouseEvent *event) -{ - QTreeWidgetItem *item = itemAt(event->pos()); - if (!item) { - setCurrentItem(NULL); - } - - QTreeWidget::mousePressEvent(event); -} - -void VDirectoryTree::keyPressEvent(QKeyEvent *event) -{ - if (VimNavigationForWidget::injectKeyPressEventForVim(this, event)) { - return; - } - - int key = event->key(); - int modifiers = event->modifiers(); - - switch (key) { - case Qt::Key_Return: - { - QTreeWidgetItem *item = currentItem(); - if (item) { - item->setExpanded(!item->isExpanded()); - } - - break; - } - - case Qt::Key_Asterisk: - { - if (modifiers == Qt::ShiftModifier) { - // *, by default will expand current item recursively. - // We build the tree recursively before the expanding. - QTreeWidgetItem *item = currentItem(); - if (item) { - buildSubTree(item, -1); - } - } - - break; - } - - default: - break; - } - - QTreeWidget::keyPressEvent(event); -} - -QTreeWidgetItem *VDirectoryTree::findVDirectory(const VDirectory *p_dir, bool *p_widget) -{ - if (p_widget) { - *p_widget = false; - } - - if (!p_dir) { - return NULL; - } else if (p_dir->getNotebookName() != m_notebook->getName()) { - return NULL; - } else if (p_dir == m_notebook->getRootDir()) { - if (p_widget) { - *p_widget = true; - } - return NULL; - } - - bool isWidget; - QTreeWidgetItem *pItem = findVDirectory(p_dir->getParentDirectory(), &isWidget); - if (pItem) { - // Iterate all its children to find the match. - int nrChild = pItem->childCount(); - for (int i = 0; i < nrChild; ++i) { - QTreeWidgetItem *item = pItem->child(i); - if (getVDirectory(item) == p_dir) { - return item; - } - } - } else if (isWidget) { - // Iterate all the top-level items. - int nrChild = topLevelItemCount(); - for (int i = 0; i < nrChild; ++i) { - QTreeWidgetItem *item = topLevelItem(i); - if (getVDirectory(item) == p_dir) { - return item; - } - } - } - - return NULL; -} - -bool VDirectoryTree::locateDirectory(const VDirectory *p_directory) -{ - if (p_directory) { - if (p_directory->getNotebook() != m_notebook) { - return false; - } - - QTreeWidgetItem *item = expandToVDirectory(p_directory); - if (item) { - setCurrentItem(item); - } - - return item; - } - - return false; -} - -QTreeWidgetItem *VDirectoryTree::expandToVDirectory(const VDirectory *p_directory) -{ - if (!p_directory - || p_directory->getNotebook() != m_notebook - || p_directory == m_notebook->getRootDir()) { - return NULL; - } - - if (p_directory->getParentDirectory() == m_notebook->getRootDir()) { - // Top-level items. - int nrChild = topLevelItemCount(); - for (int i = 0; i < nrChild; ++i) { - QTreeWidgetItem *item = topLevelItem(i); - if (getVDirectory(item) == p_directory) { - return item; - } - } - } else { - QTreeWidgetItem *pItem = expandToVDirectory(p_directory->getParentDirectory()); - if (!pItem) { - return NULL; - } - - int nrChild = pItem->childCount(); - if (nrChild == 0) { - buildSubTree(pItem, 1); - } - - nrChild = pItem->childCount(); - for (int i = 0; i < nrChild; ++i) { - QTreeWidgetItem *item = pItem->child(i); - if (getVDirectory(item) == p_directory) { - return item; - } - } - } - - return NULL; -} - -void VDirectoryTree::expandSubTree(QTreeWidgetItem *p_item) -{ - if (!p_item) { - return; - } - - VDirectory *dir = getVDirectory(p_item); - int nrChild = p_item->childCount(); - for (int i = 0; i < nrChild; ++i) { - expandSubTree(p_item->child(i)); - } - - if (dir->isExpanded()) { - Q_ASSERT(nrChild > 0); - expandItem(p_item); - } -} - -void VDirectoryTree::showNavigation() -{ - VNavigationMode::showNavigation(this); -} - -bool VDirectoryTree::handleKeyNavigation(int p_key, bool &p_succeed) -{ - static bool secondKey = false; - return VNavigationMode::handleKeyNavigation(this, - secondKey, - p_key, - p_succeed); -} - -int VDirectoryTree::getNewMagic() -{ - m_magicForClipboard = (int)QDateTime::currentDateTime().toTime_t(); - m_magicForClipboard |= qrand(); - - return m_magicForClipboard; -} - -bool VDirectoryTree::checkMagic(int p_magic) const -{ - return m_magicForClipboard == p_magic; -} - -void VDirectoryTree::sortItems() -{ - if (!m_notebook) { - return; - } - - QTreeWidgetItem *item = currentItem(); - if (item && item->parent()) { - sortItems(getVDirectory(item->parent())); - } else { - sortItems(m_notebook->getRootDir()); - } - - if (item) { - setCurrentItem(item); - } -} - -void VDirectoryTree::sortItems(VDirectory *p_dir) -{ - if (!p_dir) { - return; - } - - const QVector &dirs = p_dir->getSubDirs(); - if (dirs.size() < 2) { - return; - } - - bool isNotebook = p_dir->parent() == NULL; - - VSortDialog dialog(tr("Sort Folders"), - tr("Sort folders in %1 %3 " - "in the configuration file.") - .arg(isNotebook ? tr("notebook") : tr("folder")) - .arg(g_config->c_dataTextStyle) - .arg(isNotebook ? p_dir->getNotebook()->getName() : p_dir->getName()), - this); - QTreeWidget *tree = dialog.getTreeWidget(); - tree->clear(); - tree->setColumnCount(2); - QStringList headers; - headers << tr("Name") << tr("Created Time"); - tree->setHeaderLabels(headers); - - for (int i = 0; i < dirs.size(); ++i) { - const VDirectory *dir = dirs[i]; - Q_ASSERT(dir->isOpened()); - QString createdTime = VUtils::displayDateTime(dir->getCreatedTimeUtc().toLocalTime()); - QStringList cols; - cols << dir->getName() << createdTime; - QTreeWidgetItem *item = new QTreeWidgetItem(tree, cols); - - item->setData(0, Qt::UserRole, i); - } - - dialog.treeUpdated(); - - if (dialog.exec()) { - QVector data = dialog.getSortedData(); - Q_ASSERT(data.size() == dirs.size()); - QVector sortedIdx(data.size(), -1); - for (int i = 0; i < data.size(); ++i) { - sortedIdx[i] = data[i].toInt(); - } - - qDebug() << "sort dirs" << sortedIdx; - if (!p_dir->sortSubDirectories(sortedIdx)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to sort folders in %1 %3.") - .arg(isNotebook ? tr("notebook") : tr("folder")) - .arg(g_config->c_dataTextStyle) - .arg(isNotebook ? p_dir->getNotebook()->getName() : p_dir->getName()), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - updateItemDirectChildren(findVDirectory(p_dir)); - } -} diff --git a/src/vdirectorytree.h b/src/vdirectorytree.h deleted file mode 100644 index 399c8eba..00000000 --- a/src/vdirectorytree.h +++ /dev/null @@ -1,200 +0,0 @@ -#ifndef VDIRECTORYTREE_H -#define VDIRECTORYTREE_H - -#include -#include -#include -#include -#include -#include -#include -#include "vdirectory.h" -#include "vnotebook.h" -#include "vnavigationmode.h" -#include "vconstants.h" - -class VEditArea; -class QLabel; - -class VDirectoryTree : public QTreeWidget, public VNavigationMode -{ - Q_OBJECT -public: - explicit VDirectoryTree(QWidget *parent = 0); - - void setEditArea(VEditArea *p_editArea); - - // Locate to the item representing @p_directory. - bool locateDirectory(const VDirectory *p_directory); - - const VNotebook *currentNotebook() const; - - // Implementations for VNavigationMode. - void showNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - -signals: - void currentDirectoryChanged(VDirectory *p_directory); - - void directoryUpdated(const VDirectory *p_directory, UpdateAction p_act); - -public slots: - // Set directory tree to display a given notebook @p_notebook. - void setNotebook(VNotebook *p_notebook); - - // Create a root folder. - void newRootDirectory(); - - // View and edit info about directory. - void editDirectoryInfo(); - - // Clear and re-build the whole directory tree. - // Do not load all the sub-directories at once. - void updateDirectoryTree(); - -private slots: - // Set the state of expansion of the directory. - void handleItemExpanded(QTreeWidgetItem *p_item); - - // Set the state of expansion of the directory. - void handleItemCollapsed(QTreeWidgetItem *p_item); - - void contextMenuRequested(QPoint pos); - - // Directory selected folder. - // Currently only support single selected item. - void deleteSelectedDirectory(); - - // Create sub-directory of current item's directory. - void newSubDirectory(); - - // Current tree item changed. - void currentDirectoryItemChanged(QTreeWidgetItem *currentItem); - - // Copy selected directories. - // Will put a Json string into the clipboard which contains the information - // about copied directories. - void copySelectedDirectories(bool p_isCut = false); - - void cutSelectedDirectories(); - - // Paste directories from clipboard as sub-directories of current item. - void pasteDirectoriesFromClipboard(); - - // Open the folder's parent directory in system's file browser. - void openDirectoryLocation() const; - - // Reload the content of current directory. - void reloadFromDisk(); - - // Sort sub-folders of current item's folder. - void sortItems(); - -protected: - void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - - void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; - -private: - // Build the subtree of @p_parent recursively to the depth @p_depth. - // @p_depth: negative - infinite levels. - // Will expand the item if the corresponding directory was expanded before. - // Will treat items with children as items having been built before. - void buildSubTree(QTreeWidgetItem *p_parent, int p_depth); - - // Fill the content of a tree item according to @p_directory. - void fillTreeItem(QTreeWidgetItem *p_item, VDirectory *p_directory); - - void initShortcuts(); - - void initActions(); - - // Update @p_item's direct children only: deleted, added, renamed. - void updateItemDirectChildren(QTreeWidgetItem *p_item); - - // Find the corresponding item of @p_dir; - // Return's NULL if no item is found and it is the root directory if @p_widget is true. - QTreeWidgetItem *findVDirectory(const VDirectory *p_dir, bool *p_widget = NULL); - - QPointer getVDirectory(QTreeWidgetItem *p_item) const; - - // Paste @p_dirs as sub-directory of @p_destDir. - void pasteDirectories(VDirectory *p_destDir, - const QVector &p_dirs, - bool p_isCut); - - // Build the subtree of @p_item's children if it has not been built yet. - // We need to fill the children before showing a item to get a correct render. - void buildChildren(QTreeWidgetItem *p_item); - - // Expand/create the directory tree nodes to @p_directory. - QTreeWidgetItem *expandToVDirectory(const VDirectory *p_directory); - - // Expand the currently-built subtree of @p_item according to VDirectory.isExpanded(). - void expandSubTree(QTreeWidgetItem *p_item); - - // We use a map to save and restore current directory of each notebook. - // Try to restore current directory after changing notebook. - // Return false if no cache item found for current notebook. - bool restoreCurrentItem(); - - // Generate new magic to m_magicForClipboard. - int getNewMagic(); - - // Check if @p_magic equals to m_magicForClipboard. - bool checkMagic(int p_magic) const; - - // Check if clipboard contains valid info to paste as directories. - bool pasteAvailable() const; - - // Sort sub-directories of @p_dir. - void sortItems(VDirectory *p_dir); - - QPointer m_notebook; - - VEditArea *m_editArea; - - // Each notebook's current item's VDirectory. - QHash m_notebookCurrentDirMap; - - // Magic number for clipboard operations. - int m_magicForClipboard; - - // Actions - QAction *newRootDirAct; - QAction *newSiblingDirAct; - QAction *newSubDirAct; - QAction *deleteDirAct; - QAction *dirInfoAct; - QAction *copyAct; - QAction *cutAct; - QAction *pasteAct; - QAction *m_openLocationAct; - QAction *m_sortAct; - - // Reload content from disk. - QAction *m_reloadAct; - - static const QString c_infoShortcutSequence; - static const QString c_copyShortcutSequence; - static const QString c_cutShortcutSequence; - static const QString c_pasteShortcutSequence; -}; - -inline QPointer VDirectoryTree::getVDirectory(QTreeWidgetItem *p_item) const -{ - Q_ASSERT(p_item); - return p_item->data(0, Qt::UserRole).value(); -} - -inline void VDirectoryTree::setEditArea(VEditArea *p_editArea) -{ - m_editArea = p_editArea; -} - -inline const VNotebook *VDirectoryTree::currentNotebook() const -{ - return m_notebook; -} - -#endif // VDIRECTORYTREE_H diff --git a/src/vdocument.cpp b/src/vdocument.cpp deleted file mode 100644 index 66a9fe29..00000000 --- a/src/vdocument.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "vdocument.h" -#include "vfile.h" -#include - -VDocument::VDocument(const VFile *v_file, QObject *p_parent) - : QObject(p_parent), - m_file(v_file), - m_readyToHighlight(false) -{ -} - -void VDocument::updateText() -{ - if (m_file) { - emit textChanged(m_file->getContent()); - } -} - -void VDocument::setToc(const QString &toc, int /* baseLevel */) -{ - if (toc == m_toc) { - return; - } - m_toc = toc; - emit tocChanged(m_toc); -} - -QString VDocument::getToc() -{ - return m_toc; -} - -void VDocument::scrollToAnchor(const QString &anchor) -{ - m_header = anchor; - - emit requestScrollToAnchor(anchor); -} - -void VDocument::setHeader(const QString &anchor) -{ - if (anchor == m_header) { - return; - } - - m_header = anchor; - emit headerChanged(m_header); -} - -void VDocument::setHtml(const QString &html) -{ - if (html == m_html) { - return; - } - m_html = html; - emit htmlChanged(m_html); -} - -void VDocument::setLog(const QString &p_log) -{ - qDebug() << "JS:" << p_log; - emit logChanged(p_log); -} - -void VDocument::keyPressEvent(int p_key, bool p_ctrl, bool p_shift) -{ - emit keyPressed(p_key, p_ctrl, p_shift); -} - -void VDocument::highlightTextAsync(const QString &p_text, int p_id, int p_timeStamp) -{ - emit requestHighlightText(p_text, p_id, p_timeStamp); -} - -void VDocument::highlightTextCB(const QString &p_html, int p_id, int p_timeStamp) -{ - emit textHighlighted(p_html, p_id, p_timeStamp); -} - -void VDocument::noticeReadyToHighlightText() -{ - m_readyToHighlight = true; - emit readyToHighlightText(); -} - -void VDocument::setFile(const VFile *p_file) -{ - m_file = p_file; -} - -void VDocument::finishLogics() -{ - qDebug() << "Web side finished logics"; - emit logicsFinished(); -} diff --git a/src/vdocument.h b/src/vdocument.h deleted file mode 100644 index 9833ae0b..00000000 --- a/src/vdocument.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef VDOCUMENT_H -#define VDOCUMENT_H - -#include -#include - -class VFile; - -class VDocument : public QObject -{ - Q_OBJECT - Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged) - Q_PROPERTY(QString toc MEMBER m_toc NOTIFY tocChanged) - Q_PROPERTY(QString html MEMBER m_html NOTIFY htmlChanged) - -public: - // @p_file could be NULL. - VDocument(const VFile *p_file, QObject *p_parent = 0); - - QString getToc(); - - // Scroll to @anchor in the web. - // @anchor is the id without '#', like "toc_1". If empty, will scroll to top. - void scrollToAnchor(const QString &anchor); - - void setHtml(const QString &html); - - // Request to highlight a segment text. - // Use p_id to identify the result. - void highlightTextAsync(const QString &p_text, int p_id, int p_timeStamp); - - void setFile(const VFile *p_file); - - bool isReadyToHighlight() const; - -public slots: - // Will be called in the HTML side - - // @toc: the HTML of the TOC. - // @baseLevel: the base level of @toc, starting from 1. It is the top level - // in the @toc. - void setToc(const QString &toc, int baseLevel); - - // When the Web view has been scrolled, it will signal current header anchor. - // Empty @anchor to indicate an invalid header. - // The header does not begins with '#'. - void setHeader(const QString &anchor); - - void setLog(const QString &p_log); - void keyPressEvent(int p_key, bool p_ctrl, bool p_shift); - void updateText(); - void highlightTextCB(const QString &p_html, int p_id, int p_timeStamp); - void noticeReadyToHighlightText(); - - // Web-side handle logics (MathJax etc.) is finished. - // But the page may not finish loading, such as images. - void finishLogics(); - -signals: - void textChanged(const QString &text); - - void tocChanged(const QString &toc); - - void requestScrollToAnchor(const QString &anchor); - - // @anchor is the id of that anchor, without '#'. - void headerChanged(const QString &anchor); - void htmlChanged(const QString &html); - void logChanged(const QString &p_log); - void keyPressed(int p_key, bool p_ctrl, bool p_shift); - void requestHighlightText(const QString &p_text, int p_id, int p_timeStamp); - void textHighlighted(const QString &p_html, int p_id, int p_timeStamp); - void readyToHighlightText(); - void logicsFinished(); - -private: - QString m_toc; - QString m_header; - - // m_text does NOT contain actual content. - QString m_text; - - // When using Hoedown, m_html will contain the html content. - QString m_html; - - const VFile *m_file; - - // Whether the web side is ready to handle highlight text request. - bool m_readyToHighlight; -}; - -inline bool VDocument::isReadyToHighlight() const -{ - return m_readyToHighlight; -} -#endif // VDOCUMENT_H diff --git a/src/vdownloader.cpp b/src/vdownloader.cpp deleted file mode 100644 index 8f6ec98d..00000000 --- a/src/vdownloader.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "vdownloader.h" - -VDownloader::VDownloader(QObject *parent) - : QObject(parent) -{ - connect(&webCtrl, &QNetworkAccessManager::finished, - this, &VDownloader::handleDownloadFinished); -} - -void VDownloader::handleDownloadFinished(QNetworkReply *reply) -{ - data = reply->readAll(); - reply->deleteLater(); - qDebug() << "VDownloader receive" << reply->url().toString(); - emit downloadFinished(data, reply->url().toString()); -} - -void VDownloader::download(const QUrl &p_url) -{ - if (!p_url.isValid()) { - return; - } - - QNetworkRequest request(p_url); - webCtrl.get(request); - qDebug() << "VDownloader get" << p_url.toString(); -} diff --git a/src/vdownloader.h b/src/vdownloader.h deleted file mode 100644 index 31e20877..00000000 --- a/src/vdownloader.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef VDOWNLOADER_H -#define VDOWNLOADER_H - -#include -#include -#include -#include -#include -#include - -class VDownloader : public QObject -{ - Q_OBJECT -public: - explicit VDownloader(QObject *parent = 0); - void download(const QUrl &p_url); - -signals: - void downloadFinished(const QByteArray &data, const QString &url); - -private slots: - void handleDownloadFinished(QNetworkReply *reply); - -private: - QNetworkAccessManager webCtrl; - QByteArray data; -}; - -#endif // VDOWNLOADER_H diff --git a/src/vedit.cpp b/src/vedit.cpp deleted file mode 100644 index 341bf2ff..00000000 --- a/src/vedit.cpp +++ /dev/null @@ -1,1427 +0,0 @@ -#include -#include -#include -#include "vedit.h" -#include "vnote.h" -#include "vconfigmanager.h" -#include "vtableofcontent.h" -#include "utils/vutils.h" -#include "utils/veditutils.h" -#include "utils/vmetawordmanager.h" -#include "veditoperations.h" -#include "vedittab.h" -#include "dialog/vinsertlinkdialog.h" -#include "utils/viconutils.h" - -extern VConfigManager *g_config; - -extern VNote *g_vnote; - -extern VMetaWordManager *g_mwMgr; - -VEdit::VEdit(VFile *p_file, QWidget *p_parent) - : QTextEdit(p_parent), m_file(p_file), - m_editOps(NULL), m_enableInputMethod(true) -{ - const int labelTimerInterval = 500; - const int extraSelectionHighlightTimer = 500; - const int labelSize = 64; - - m_selectedWordColor = QColor(g_config->getEditorSelectedWordBg()); - m_searchedWordColor = QColor(g_config->getEditorSearchedWordBg()); - m_searchedWordCursorColor = QColor(g_config->getEditorSearchedWordCursorBg()); - m_incrementalSearchedWordColor = QColor(g_config->getEditorIncrementalSearchedWordBg()); - m_trailingSpaceColor = QColor(g_config->getEditorTrailingSpaceBg()); - - QPixmap wrapPixmap(":/resources/icons/search_wrap.svg"); - m_wrapLabel = new QLabel(this); - m_wrapLabel->setPixmap(wrapPixmap.scaled(labelSize, labelSize)); - m_wrapLabel->hide(); - m_labelTimer = new QTimer(this); - m_labelTimer->setSingleShot(true); - m_labelTimer->setInterval(labelTimerInterval); - connect(m_labelTimer, &QTimer::timeout, - this, &VEdit::labelTimerTimeout); - - m_highlightTimer = new QTimer(this); - m_highlightTimer->setSingleShot(true); - m_highlightTimer->setInterval(extraSelectionHighlightTimer); - connect(m_highlightTimer, &QTimer::timeout, - this, &VEdit::doHighlightExtraSelections); - - m_extraSelections.resize((int)SelectionId::MaxSelection); - - updateFontAndPalette(); - - m_config.init(QFontMetrics(font()), false); - updateConfig(); - - connect(this, &VEdit::cursorPositionChanged, - this, &VEdit::handleCursorPositionChanged); - - connect(this, &VEdit::selectionChanged, - this, &VEdit::highlightSelectedWord); - - m_lineNumberArea = new LineNumberArea(this); - connect(document(), &QTextDocument::blockCountChanged, - this, &VEdit::updateLineNumberAreaMargin); - connect(this, &QTextEdit::textChanged, - this, &VEdit::updateLineNumberArea); - connect(verticalScrollBar(), &QScrollBar::valueChanged, - this, &VEdit::updateLineNumberArea); - - updateLineNumberAreaMargin(); - - connect(document(), &QTextDocument::contentsChange, - this, &VEdit::updateBlockLineDistanceHeight); -} - -VEdit::~VEdit() -{ -} - -void VEdit::updateConfig() -{ - m_config.update(QFontMetrics(font())); - - if (m_config.m_tabStopWidth > 0) { - setTabStopWidth(m_config.m_tabStopWidth); - } - - emit configUpdated(); -} - -void VEdit::beginEdit() -{ - updateFontAndPalette(); - - updateConfig(); - - setReadOnlyAndHighlight(false); - - setModified(false); -} - -void VEdit::endEdit() -{ - setReadOnlyAndHighlight(true); -} - -void VEdit::saveFile() -{ - Q_ASSERT(m_file->isModifiable()); - - if (!document()->isModified()) { - return; - } - - m_file->setContent(toHtml()); - setModified(false); -} - -void VEdit::reloadFile() -{ - setHtml(m_file->getContent()); - - setModified(false); -} - -bool VEdit::scrollToBlock(int p_blockNumber) -{ - QTextBlock block = document()->findBlockByNumber(p_blockNumber); - if (block.isValid()) { - VEditUtils::scrollBlockInPage(this, block.blockNumber(), 0); - moveCursor(QTextCursor::EndOfBlock); - return true; - } - - return false; -} - -bool VEdit::isModified() const -{ - return document()->isModified(); -} - -void VEdit::setModified(bool p_modified) -{ - document()->setModified(p_modified); -} - -void VEdit::insertImage() -{ - if (m_editOps) { - m_editOps->insertImage(); - } -} - -void VEdit::insertLink() -{ - if (!m_editOps) { - return; - } - - QString text; - QString linkText, linkUrl; - QTextCursor cursor = textCursor(); - if (cursor.hasSelection()) { - text = VEditUtils::selectedText(cursor).trimmed(); - // Only pure space is accepted. - QRegExp reg("[\\S ]*"); - if (reg.exactMatch(text)) { - QUrl url = QUrl::fromUserInput(text, - m_file->fetchBasePath()); - QRegExp urlReg("[\\.\\\\/]"); - if (url.isValid() - && text.contains(urlReg)) { - // Url. - linkUrl = text; - } else { - // Text. - linkText = text; - } - } - } - - VInsertLinkDialog dialog(tr("Insert Link"), - "", - "", - linkText, - linkUrl, - this); - if (dialog.exec() == QDialog::Accepted) { - linkText = dialog.getLinkText(); - linkUrl = dialog.getLinkUrl(); - Q_ASSERT(!linkText.isEmpty() && !linkUrl.isEmpty()); - - m_editOps->insertLink(linkText, linkUrl); - } -} - -bool VEdit::peekText(const QString &p_text, uint p_options, bool p_forward) -{ - if (p_text.isEmpty()) { - makeBlockVisible(document()->findBlock(textCursor().selectionStart())); - highlightIncrementalSearchedWord(QTextCursor()); - return false; - } - - bool wrapped = false; - QTextCursor retCursor; - bool found = findTextHelper(p_text, p_options, p_forward, - p_forward ? textCursor().position() + 1 - : textCursor().position(), - wrapped, retCursor); - if (found) { - makeBlockVisible(document()->findBlock(retCursor.selectionStart())); - highlightIncrementalSearchedWord(retCursor); - } - - return found; -} - -// Use QTextEdit::find() instead of QTextDocument::find() because the later has -// bugs in searching backward. -bool VEdit::findTextHelper(const QString &p_text, uint p_options, - bool p_forward, int p_start, - bool &p_wrapped, QTextCursor &p_cursor) -{ - p_wrapped = false; - bool found = false; - - // Options - QTextDocument::FindFlags findFlags; - bool caseSensitive = false; - if (p_options & FindOption::CaseSensitive) { - findFlags |= QTextDocument::FindCaseSensitively; - caseSensitive = true; - } - - if (p_options & FindOption::WholeWordOnly) { - findFlags |= QTextDocument::FindWholeWords; - } - - if (!p_forward) { - findFlags |= QTextDocument::FindBackward; - } - - // Use regular expression - bool useRegExp = false; - QRegExp exp; - if (p_options & FindOption::RegularExpression) { - useRegExp = true; - exp = QRegExp(p_text, - caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); - } - - // Store current state of the cursor. - QTextCursor cursor = textCursor(); - if (cursor.position() != p_start) { - if (p_start < 0) { - p_start = 0; - } else if (p_start > document()->characterCount()) { - p_start = document()->characterCount(); - } - - QTextCursor startCursor = cursor; - startCursor.setPosition(p_start); - setTextCursor(startCursor); - } - - while (!found) { - if (useRegExp) { - found = find(exp, findFlags); - } else { - found = find(p_text, findFlags); - } - - if (p_wrapped) { - break; - } - - if (!found) { - // Wrap to the other end of the document to search again. - p_wrapped = true; - QTextCursor wrapCursor = textCursor(); - if (p_forward) { - wrapCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); - } else { - wrapCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); - } - - setTextCursor(wrapCursor); - } - } - - if (found) { - p_cursor = textCursor(); - } - - // Restore the original cursor. - setTextCursor(cursor); - - return found; -} - -QList VEdit::findTextAll(const QString &p_text, uint p_options) -{ - QList results; - if (p_text.isEmpty()) { - return results; - } - // Options - QTextDocument::FindFlags findFlags; - bool caseSensitive = false; - if (p_options & FindOption::CaseSensitive) { - findFlags |= QTextDocument::FindCaseSensitively; - caseSensitive = true; - } - if (p_options & FindOption::WholeWordOnly) { - findFlags |= QTextDocument::FindWholeWords; - } - // Use regular expression - bool useRegExp = false; - QRegExp exp; - if (p_options & FindOption::RegularExpression) { - useRegExp = true; - exp = QRegExp(p_text, - caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); - } - int startPos = 0; - QTextCursor cursor; - QTextDocument *doc = document(); - while (true) { - if (useRegExp) { - cursor = doc->find(exp, startPos, findFlags); - } else { - cursor = doc->find(p_text, startPos, findFlags); - } - if (cursor.isNull()) { - break; - } else { - results.append(cursor); - startPos = cursor.selectionEnd(); - } - } - return results; -} - -bool VEdit::findText(const QString &p_text, uint p_options, bool p_forward, - QTextCursor *p_cursor, QTextCursor::MoveMode p_moveMode) -{ - clearIncrementalSearchedWordHighlight(); - - if (p_text.isEmpty()) { - clearSearchedWordHighlight(); - return false; - } - - QTextCursor cursor = textCursor(); - bool wrapped = false; - QTextCursor retCursor; - int matches = 0; - int start = p_forward ? cursor.position() + 1 : cursor.position(); - if (p_cursor) { - start = p_forward ? p_cursor->position() + 1 : p_cursor->position(); - } - - bool found = findTextHelper(p_text, p_options, p_forward, start, - wrapped, retCursor); - if (found) { - Q_ASSERT(!retCursor.isNull()); - if (wrapped) { - showWrapLabel(); - } - - if (p_cursor) { - p_cursor->setPosition(retCursor.selectionStart(), p_moveMode); - } else { - cursor.setPosition(retCursor.selectionStart(), p_moveMode); - setTextCursor(cursor); - } - - highlightSearchedWord(p_text, p_options); - highlightSearchedWordUnderCursor(retCursor); - matches = m_extraSelections[(int)SelectionId::SearchedKeyword].size(); - } else { - clearSearchedWordHighlight(); - } - - if (matches == 0) { - statusMessage(tr("Found no match")); - } else { - statusMessage(tr("Found %1 %2").arg(matches) - .arg(matches > 1 ? tr("matches") : tr("match"))); - } - - return found; -} - -void VEdit::replaceText(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext) -{ - QTextCursor cursor = textCursor(); - bool wrapped = false; - QTextCursor retCursor; - bool found = findTextHelper(p_text, p_options, true, - cursor.position(), wrapped, retCursor); - if (found) { - if (retCursor.selectionStart() == cursor.position()) { - // Matched. - retCursor.beginEditBlock(); - retCursor.insertText(p_replaceText); - retCursor.endEditBlock(); - setTextCursor(retCursor); - } - - if (p_findNext) { - findText(p_text, p_options, true); - } - } -} - -void VEdit::replaceTextAll(const QString &p_text, uint p_options, - const QString &p_replaceText) -{ - // Replace from the start to the end and restore the cursor. - QTextCursor cursor = textCursor(); - int nrReplaces = 0; - QTextCursor tmpCursor = cursor; - tmpCursor.setPosition(0); - setTextCursor(tmpCursor); - int start = tmpCursor.position(); - while (true) { - bool wrapped = false; - QTextCursor retCursor; - bool found = findTextHelper(p_text, p_options, true, - start, wrapped, retCursor); - if (!found) { - break; - } else { - if (wrapped) { - // Wrap back. - break; - } - - nrReplaces++; - retCursor.beginEditBlock(); - retCursor.insertText(p_replaceText); - retCursor.endEditBlock(); - setTextCursor(retCursor); - start = retCursor.position(); - } - } - - // Restore cursor position. - cursor.clearSelection(); - setTextCursor(cursor); - qDebug() << "replace all" << nrReplaces << "occurences"; - - emit statusMessage(tr("Replace %1 %2").arg(nrReplaces) - .arg(nrReplaces > 1 ? tr("occurences") - : tr("occurence"))); -} - -void VEdit::showWrapLabel() -{ - int labelW = m_wrapLabel->width(); - int labelH = m_wrapLabel->height(); - int x = (width() - labelW) / 2; - int y = (height() - labelH) / 2; - if (x < 0) { - x = 0; - } - if (y < 0) { - y = 0; - } - m_wrapLabel->move(x, y); - m_wrapLabel->show(); - m_labelTimer->stop(); - m_labelTimer->start(); -} - -void VEdit::labelTimerTimeout() -{ - m_wrapLabel->hide(); -} - -void VEdit::updateFontAndPalette() -{ - setFont(g_config->getBaseEditFont()); - setPalette(g_config->getBaseEditPalette()); -} - -void VEdit::highlightExtraSelections(bool p_now) -{ - m_highlightTimer->stop(); - if (p_now) { - doHighlightExtraSelections(); - } else { - m_highlightTimer->start(); - } -} - -void VEdit::doHighlightExtraSelections() -{ - int nrExtra = m_extraSelections.size(); - Q_ASSERT(nrExtra == (int)SelectionId::MaxSelection); - QList extraSelects; - for (int i = 0; i < nrExtra; ++i) { - extraSelects.append(m_extraSelections[i]); - } - - setExtraSelections(extraSelects); -} - -void VEdit::highlightCurrentLine() -{ - QList &selects = m_extraSelections[(int)SelectionId::CurrentLine]; - if (g_config->getHighlightCursorLine() && !isReadOnly()) { - // Need to highlight current line. - selects.clear(); - - // A long block maybe splited into multiple visual lines. - QTextEdit::ExtraSelection select; - select.format.setBackground(m_config.m_cursorLineBg); - select.format.setProperty(QTextFormat::FullWidthSelection, true); - - QTextCursor cursor = textCursor(); - if (m_config.m_highlightWholeBlock) { - cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor, 1); - QTextBlock block = cursor.block(); - int blockEnd = block.position() + block.length(); - int pos = -1; - while (cursor.position() < blockEnd && pos != cursor.position()) { - QTextEdit::ExtraSelection newSelect = select; - newSelect.cursor = cursor; - selects.append(newSelect); - - pos = cursor.position(); - cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, 1); - } - } else { - cursor.clearSelection(); - select.cursor = cursor; - selects.append(select); - } - } else { - // Need to clear current line highlight. - if (selects.isEmpty()) { - return; - } - - selects.clear(); - } - - highlightExtraSelections(true); -} - -void VEdit::highlightSelectedWord() -{ - QList &selects = m_extraSelections[(int)SelectionId::SelectedWord]; - if (!g_config->getHighlightSelectedWord()) { - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - - return; - } - - QString text = textCursor().selectedText().trimmed(); - if (text.isEmpty() || wordInSearchedSelection(text)) { - selects.clear(); - highlightExtraSelections(true); - return; - } - - QTextCharFormat format; - format.setBackground(m_selectedWordColor); - highlightTextAll(text, FindOption::CaseSensitive, SelectionId::SelectedWord, - format); -} - -// Do not highlight trailing spaces with current cursor right behind. -static void trailingSpaceFilter(VEdit *p_editor, QList &p_result) -{ - QTextCursor cursor = p_editor->textCursor(); - if (!cursor.atBlockEnd()) { - return; - } - - int cursorPos = cursor.position(); - for (auto it = p_result.begin(); it != p_result.end(); ++it) { - if (it->cursor.selectionEnd() == cursorPos) { - p_result.erase(it); - - // There will be only one. - return; - } - } -} - -void VEdit::highlightTrailingSpace() -{ - if (!g_config->getEnableTrailingSpaceHighlight()) { - QList &selects = m_extraSelections[(int)SelectionId::TrailingSapce]; - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - return; - } - - QTextCharFormat format; - format.setBackground(m_trailingSpaceColor); - QString text("\\s+$"); - highlightTextAll(text, FindOption::RegularExpression, - SelectionId::TrailingSapce, format, - trailingSpaceFilter); -} - -bool VEdit::wordInSearchedSelection(const QString &p_text) -{ - QString text = p_text.trimmed(); - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeyword]; - for (int i = 0; i < selects.size(); ++i) { - QString searchedWord = selects[i].cursor.selectedText(); - if (text == searchedWord.trimmed()) { - return true; - } - } - return false; -} - -void VEdit::highlightTextAll(const QString &p_text, uint p_options, - SelectionId p_id, QTextCharFormat p_format, - void (*p_filter)(VEdit *, QList &)) -{ - QList &selects = m_extraSelections[(int)p_id]; - if (!p_text.isEmpty()) { - selects.clear(); - - QList occurs = findTextAll(p_text, p_options); - for (int i = 0; i < occurs.size(); ++i) { - QTextEdit::ExtraSelection select; - select.format = p_format; - select.cursor = occurs[i]; - selects.append(select); - } - } else { - if (selects.isEmpty()) { - return; - } - selects.clear(); - } - - if (p_filter) { - p_filter(this, selects); - } - - highlightExtraSelections(); -} - -void VEdit::highlightSearchedWord(const QString &p_text, uint p_options) -{ - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeyword]; - if (!g_config->getHighlightSearchedWord() || p_text.isEmpty()) { - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - - return; - } - - QTextCharFormat format; - format.setBackground(m_searchedWordColor); - highlightTextAll(p_text, p_options, SelectionId::SearchedKeyword, format); -} - -void VEdit::highlightSearchedWordUnderCursor(const QTextCursor &p_cursor) -{ - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeywordUnderCursor]; - if (!p_cursor.hasSelection()) { - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - - return; - } - - selects.clear(); - QTextEdit::ExtraSelection select; - select.format.setBackground(m_searchedWordCursorColor); - select.cursor = p_cursor; - selects.append(select); - - highlightExtraSelections(true); -} - -void VEdit::highlightIncrementalSearchedWord(const QTextCursor &p_cursor) -{ - QList &selects = m_extraSelections[(int)SelectionId::IncrementalSearchedKeyword]; - if (!g_config->getHighlightSearchedWord() || !p_cursor.hasSelection()) { - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - - return; - } - - selects.clear(); - QTextEdit::ExtraSelection select; - select.format.setBackground(m_incrementalSearchedWordColor); - select.cursor = p_cursor; - selects.append(select); - - highlightExtraSelections(true); -} - -void VEdit::clearSearchedWordHighlight() -{ - clearIncrementalSearchedWordHighlight(false); - clearSearchedWordUnderCursorHighlight(false); - - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeyword]; - if (selects.isEmpty()) { - return; - } - - selects.clear(); - highlightExtraSelections(true); -} - -void VEdit::clearSearchedWordUnderCursorHighlight(bool p_now) -{ - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeywordUnderCursor]; - if (selects.isEmpty()) { - return; - } - - selects.clear(); - highlightExtraSelections(p_now); -} - -void VEdit::clearIncrementalSearchedWordHighlight(bool p_now) -{ - QList &selects = m_extraSelections[(int)SelectionId::IncrementalSearchedKeyword]; - if (selects.isEmpty()) { - return; - } - - selects.clear(); - highlightExtraSelections(p_now); -} - -void VEdit::contextMenuEvent(QContextMenuEvent *p_event) -{ - QMenu *menu = createStandardContextMenu(); - menu->setToolTipsVisible(true); - - const QList actions = menu->actions(); - - if (!textCursor().hasSelection()) { - VEditTab *editTab = dynamic_cast(parent()); - V_ASSERT(editTab); - if (editTab->isEditMode()) { - QAction *saveExitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/save_exit.svg"), - tr("&Save Changes And Read"), this); - saveExitAct->setToolTip(tr("Save changes and exit edit mode")); - connect(saveExitAct, &QAction::triggered, - this, &VEdit::handleSaveExitAct); - - QAction *discardExitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/discard_exit.svg"), - tr("&Discard Changes And Read"), this); - discardExitAct->setToolTip(tr("Discard changes and exit edit mode")); - connect(discardExitAct, &QAction::triggered, - this, &VEdit::handleDiscardExitAct); - - menu->insertAction(actions.isEmpty() ? NULL : actions[0], discardExitAct); - menu->insertAction(discardExitAct, saveExitAct); - if (!actions.isEmpty()) { - menu->insertSeparator(actions[0]); - } - } else if (m_file->isModifiable()) { - // HTML. - QAction *editAct= new QAction(VIconUtils::menuIcon(":/resources/icons/edit_note.svg"), - tr("&Edit"), this); - editAct->setToolTip(tr("Edit current note")); - connect(editAct, &QAction::triggered, - this, &VEdit::handleEditAct); - menu->insertAction(actions.isEmpty() ? NULL : actions[0], editAct); - // actions does not contain editAction. - if (!actions.isEmpty()) { - menu->insertSeparator(actions[0]); - } - } - } - - alterContextMenu(menu, actions); - - menu->exec(p_event->globalPos()); - delete menu; -} - -void VEdit::handleSaveExitAct() -{ - emit saveAndRead(); -} - -void VEdit::handleDiscardExitAct() -{ - emit discardAndRead(); -} - -void VEdit::handleEditAct() -{ - emit editNote(); -} - -VFile *VEdit::getFile() const -{ - return m_file; -} - -void VEdit::handleCursorPositionChanged() -{ - static QTextCursor lastCursor; - - QTextCursor cursor = textCursor(); - if (lastCursor.isNull() || cursor.blockNumber() != lastCursor.blockNumber()) { - highlightCurrentLine(); - highlightTrailingSpace(); - } else { - // Judge whether we have trailing space at current line. - QString text = cursor.block().text(); - if (text.rbegin()->isSpace()) { - highlightTrailingSpace(); - } - - // Handle word-wrap in one block. - // Highlight current line if in different visual line. - if ((lastCursor.positionInBlock() - lastCursor.columnNumber()) != - (cursor.positionInBlock() - cursor.columnNumber())) { - highlightCurrentLine(); - } - } - - lastCursor = cursor; -} - -VEditConfig &VEdit::getConfig() -{ - return m_config; -} - -void VEdit::mousePressEvent(QMouseEvent *p_event) -{ - if (p_event->button() == Qt::LeftButton - && p_event->modifiers() == Qt::ControlModifier - && !textCursor().hasSelection()) { - m_oriMouseX = p_event->x(); - m_oriMouseY = p_event->y(); - m_readyToScroll = true; - m_mouseMoveScrolled = false; - p_event->accept(); - return; - } - - m_readyToScroll = false; - m_mouseMoveScrolled = false; - - QTextEdit::mousePressEvent(p_event); - - emit selectionChangedByMouse(textCursor().hasSelection()); -} - -void VEdit::mouseReleaseEvent(QMouseEvent *p_event) -{ - if (m_mouseMoveScrolled || m_readyToScroll) { - viewport()->setCursor(Qt::IBeamCursor); - m_readyToScroll = false; - m_mouseMoveScrolled = false; - p_event->accept(); - return; - } - - m_readyToScroll = false; - m_mouseMoveScrolled = false; - - QTextEdit::mouseReleaseEvent(p_event); -} - -void VEdit::mouseMoveEvent(QMouseEvent *p_event) -{ - const int threshold = 5; - - if (m_readyToScroll) { - int deltaX = p_event->x() - m_oriMouseX; - int deltaY = p_event->y() - m_oriMouseY; - - if (qAbs(deltaX) >= threshold || qAbs(deltaY) >= threshold) { - m_oriMouseX = p_event->x(); - m_oriMouseY = p_event->y(); - - if (!m_mouseMoveScrolled) { - m_mouseMoveScrolled = true; - viewport()->setCursor(Qt::SizeAllCursor); - } - - QScrollBar *verBar = verticalScrollBar(); - QScrollBar *horBar = horizontalScrollBar(); - if (verBar->isVisible()) { - verBar->setValue(verBar->value() - deltaY); - } - - if (horBar->isVisible()) { - horBar->setValue(horBar->value() - deltaX); - } - } - - p_event->accept(); - return; - } - - QTextEdit::mouseMoveEvent(p_event); - - emit selectionChangedByMouse(textCursor().hasSelection()); -} - -void VEdit::requestUpdateVimStatus() -{ - if (m_editOps) { - m_editOps->requestUpdateVimStatus(); - } else { - emit vimStatusUpdated(NULL); - } -} - -bool VEdit::jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat) -{ - Q_UNUSED(p_forward); - Q_UNUSED(p_relativeLevel); - Q_UNUSED(p_repeat); - return false; -} - -QVariant VEdit::inputMethodQuery(Qt::InputMethodQuery p_query) const -{ - if (p_query == Qt::ImEnabled) { - return m_enableInputMethod; - } - - return QTextEdit::inputMethodQuery(p_query); -} - -void VEdit::setInputMethodEnabled(bool p_enabled) -{ - if (m_enableInputMethod != p_enabled) { - m_enableInputMethod = p_enabled; - - QInputMethod *im = QGuiApplication::inputMethod(); - im->reset(); - // Ask input method to query current state, which will call inputMethodQuery(). - im->update(Qt::ImEnabled); - } -} - -void VEdit::decorateText(TextDecoration p_decoration) -{ - if (m_editOps) { - m_editOps->decorateText(p_decoration); - } -} - -void VEdit::updateLineNumberAreaMargin() -{ - int width = 0; - if (g_config->getEditorLineNumber()) { - width = m_lineNumberArea->calculateWidth(); - } - - setViewportMargins(width, 0, 0, 0); -} - -void VEdit::updateLineNumberArea() -{ - if (g_config->getEditorLineNumber()) { - if (!m_lineNumberArea->isVisible()) { - updateLineNumberAreaMargin(); - m_lineNumberArea->show(); - } - - m_lineNumberArea->update(); - } else if (m_lineNumberArea->isVisible()) { - updateLineNumberAreaMargin(); - m_lineNumberArea->hide(); - } -} - -void VEdit::resizeEvent(QResizeEvent *p_event) -{ - QTextEdit::resizeEvent(p_event); - - if (g_config->getEditorLineNumber()) { - QRect rect = contentsRect(); - m_lineNumberArea->setGeometry(QRect(rect.left(), - rect.top(), - m_lineNumberArea->calculateWidth(), - rect.height())); - } -} - -void VEdit::lineNumberAreaPaintEvent(QPaintEvent *p_event) -{ - int lineNumberType = g_config->getEditorLineNumber(); - if (!lineNumberType) { - updateLineNumberAreaMargin(); - m_lineNumberArea->hide(); - return; - } - - QPainter painter(m_lineNumberArea); - painter.fillRect(p_event->rect(), g_config->getEditorLineNumberBg()); - - QAbstractTextDocumentLayout *layout = document()->documentLayout(); - - QTextBlock block = firstVisibleBlock(); - if (!block.isValid()) { - return; - } - - int blockNumber = block.blockNumber(); - int offsetY = contentOffsetY(); - QRectF rect = layout->blockBoundingRect(block); - int top = offsetY + (int)rect.y(); - int bottom = top + (int)rect.height(); - int eventTop = p_event->rect().top(); - int eventBtm = p_event->rect().bottom(); - const int digitHeight = m_lineNumberArea->getDigitHeight(); - const int curBlockNumber = textCursor().block().blockNumber(); - const QString &fg = g_config->getEditorLineNumberFg(); - const int lineDistanceHeight = m_config.m_lineDistanceHeight; - painter.setPen(fg); - - // Display line number only in code block. - if (lineNumberType == 3) { - if (m_file->getDocType() != DocType::Markdown) { - return; - } - - int number = 0; - while (block.isValid() && top <= eventBtm) { - int blockState = block.userState(); - switch (blockState) { - case HighlightBlockState::CodeBlockStart: - Q_ASSERT(number == 0); - number = 1; - break; - - case HighlightBlockState::CodeBlockEnd: - number = 0; - break; - - case HighlightBlockState::CodeBlock: - if (number == 0) { - // Need to find current line number in code block. - QTextBlock startBlock = block.previous(); - while (startBlock.isValid()) { - if (startBlock.userState() == HighlightBlockState::CodeBlockStart) { - number = block.blockNumber() - startBlock.blockNumber(); - break; - } - - startBlock = startBlock.previous(); - } - } - - break; - - default: - break; - } - - if (blockState == HighlightBlockState::CodeBlock) { - if (block.isVisible() && bottom >= eventTop) { - QString numberStr = QString::number(number); - painter.drawText(0, - top + 2, - m_lineNumberArea->width(), - digitHeight, - Qt::AlignRight, - numberStr); - } - - ++number; - } - - block = block.next(); - top = bottom; - bottom = top + (int)layout->blockBoundingRect(block).height() + lineDistanceHeight; - } - - return; - } - - // Handle lineNumberType 1 and 2. - Q_ASSERT(lineNumberType == 1 || lineNumberType == 2); - while (block.isValid() && top <= eventBtm) { - if (block.isVisible() && bottom >= eventTop) { - bool currentLine = false; - int number = blockNumber + 1; - if (lineNumberType == 2) { - number = blockNumber - curBlockNumber; - if (number == 0) { - currentLine = true; - number = blockNumber + 1; - } else if (number < 0) { - number = -number; - } - } else if (blockNumber == curBlockNumber) { - currentLine = true; - } - - QString numberStr = QString::number(number); - - if (currentLine) { - QFont font = painter.font(); - font.setBold(true); - painter.setFont(font); - } - - painter.drawText(0, - top + 2, - m_lineNumberArea->width(), - digitHeight, - Qt::AlignRight, - numberStr); - - if (currentLine) { - QFont font = painter.font(); - font.setBold(false); - painter.setFont(font); - } - } - - block = block.next(); - top = bottom; - bottom = top + (int)layout->blockBoundingRect(block).height() + lineDistanceHeight; - ++blockNumber; - } -} - -int VEdit::contentOffsetY() -{ - int offsety = 0; - QScrollBar *sb = verticalScrollBar(); - offsety = sb->value(); - return -offsety; -} - -QTextBlock VEdit::firstVisibleBlock() -{ - QTextDocument *doc = document(); - QAbstractTextDocumentLayout *layout = doc->documentLayout(); - int offsetY = contentOffsetY(); - - // Binary search. - int idx = -1; - int start = 0, end = doc->blockCount() - 1; - while (start <= end) { - int mid = start + (end - start) / 2; - QTextBlock block = doc->findBlockByNumber(mid); - if (!block.isValid()) { - break; - } - - int y = offsetY + (int)layout->blockBoundingRect(block).y(); - if (y == 0) { - return block; - } else if (y < 0) { - start = mid + 1; - } else { - if (idx == -1 || mid < idx) { - idx = mid; - } - - end = mid - 1; - } - } - - if (idx != -1) { - return doc->findBlockByNumber(idx); - } - - // Linear search. - qDebug() << "fall back to linear search for first visible block"; - QTextBlock block = doc->begin(); - while (block.isValid()) { - int y = offsetY + (int)layout->blockBoundingRect(block).y(); - if (y >= 0) { - return block; - } - - block = block.next(); - } - - return QTextBlock(); -} - -int LineNumberArea::calculateWidth() const -{ - int bc = m_document->blockCount(); - if (m_blockCount == bc) { - return m_width; - } - - const_cast(this)->m_blockCount = bc; - int digits = 1; - int max = qMax(1, m_blockCount); - while (max >= 10) { - max /= 10; - ++digits; - } - - int width = m_digitWidth * digits; - const_cast(this)->m_width = width; - - return m_width; -} - -void VEdit::makeBlockVisible(const QTextBlock &p_block) -{ - if (!p_block.isValid() || !p_block.isVisible()) { - return; - } - - QScrollBar *vbar = verticalScrollBar(); - if (!vbar || !vbar->isVisible()) { - // No vertical scrollbar. No need to scroll. - return; - } - - QAbstractTextDocumentLayout *layout = document()->documentLayout(); - int height = rect().height(); - QScrollBar *hbar = horizontalScrollBar(); - if (hbar && hbar->isVisible()) { - height -= hbar->height(); - } - - bool moved = false; - - QRectF rect = layout->blockBoundingRect(p_block); - int y = contentOffsetY() + (int)rect.y(); - int rectHeight = (int)rect.height(); - - // Handle the case rectHeight >= height. - if (rectHeight >= height) { - if (y <= 0) { - if (y + rectHeight < height) { - // Need to scroll up. - while (y + rectHeight < height && vbar->value() > vbar->minimum()) { - moved = true; - vbar->setValue(vbar->value() - vbar->singleStep()); - rect = layout->blockBoundingRect(p_block); - rectHeight = (int)rect.height(); - y = contentOffsetY() + (int)rect.y(); - } - } - } else { - // Need to scroll down. - while (y > 0 && vbar->value() < vbar->maximum()) { - moved = true; - vbar->setValue(vbar->value() + vbar->singleStep()); - rect = layout->blockBoundingRect(p_block); - rectHeight = (int)rect.height(); - y = contentOffsetY() + (int)rect.y(); - } - } - - if (moved) { - qDebug() << "scroll to make huge block visible"; - } - - return; - } - - while (y < 0 && vbar->value() > vbar->minimum()) { - moved = true; - vbar->setValue(vbar->value() - vbar->singleStep()); - rect = layout->blockBoundingRect(p_block); - rectHeight = (int)rect.height(); - y = contentOffsetY() + (int)rect.y(); - } - - if (moved) { - qDebug() << "scroll page down to make block visible"; - return; - } - - while (y + rectHeight > height && vbar->value() < vbar->maximum()) { - moved = true; - vbar->setValue(vbar->value() + vbar->singleStep()); - rect = layout->blockBoundingRect(p_block); - rectHeight = (int)rect.height(); - y = contentOffsetY() + (int)rect.y(); - } - - if (moved) { - qDebug() << "scroll page up to make block visible"; - } -} - -bool VEdit::isBlockVisible(const QTextBlock &p_block) -{ - if (!p_block.isValid() || !p_block.isVisible()) { - return false; - } - - QScrollBar *vbar = verticalScrollBar(); - if (!vbar || !vbar->isVisible()) { - // No vertical scrollbar. - return true; - } - - QAbstractTextDocumentLayout *layout = document()->documentLayout(); - int height = rect().height(); - QScrollBar *hbar = horizontalScrollBar(); - if (hbar && hbar->isVisible()) { - height -= hbar->height(); - } - - QRectF rect = layout->blockBoundingRect(p_block); - int y = contentOffsetY() + (int)rect.y(); - int rectHeight = (int)rect.height(); - - return (y >= 0 && y < height) || (y < 0 && y + rectHeight > 0); -} - -void VEdit::alterContextMenu(QMenu *p_menu, const QList &p_actions) -{ - Q_UNUSED(p_menu); - Q_UNUSED(p_actions); -} - -void VEdit::updateBlockLineDistanceHeight(int p_pos, - int p_charsRemoved, - int p_charsAdded) -{ - if ((p_charsRemoved == 0 && p_charsAdded == 0) - || m_config.m_lineDistanceHeight <= 0) { - return; - } - - QTextDocument *doc = document(); - QTextBlock block = doc->findBlock(p_pos); - QTextBlock lastBlock = doc->findBlock(p_pos + p_charsRemoved + p_charsAdded); - QTextCursor cursor(block); - bool changed = false; - while (block.isValid()) { - cursor.setPosition(block.position()); - QTextBlockFormat fmt = cursor.blockFormat(); - if (fmt.lineHeightType() != QTextBlockFormat::LineDistanceHeight - || fmt.lineHeight() != m_config.m_lineDistanceHeight) { - fmt.setLineHeight(m_config.m_lineDistanceHeight, - QTextBlockFormat::LineDistanceHeight); - if (!changed) { - changed = true; - cursor.joinPreviousEditBlock(); - } - - cursor.mergeBlockFormat(fmt); - qDebug() << "merge block format line distance" << block.blockNumber(); - } - - if (block == lastBlock) { - break; - } - - block = block.next(); - } - - if (changed) { - cursor.endEditBlock(); - } -} - -void VEdit::evaluateMagicWords() -{ - QString text; - QTextCursor cursor = textCursor(); - if (!cursor.hasSelection()) { - // Get the WORD in current cursor. - int start, end; - VEditUtils::findCurrentWORD(cursor, start, end); - - if (start == end) { - return; - } else { - cursor.setPosition(start); - cursor.setPosition(end, QTextCursor::KeepAnchor); - } - } - - text = VEditUtils::selectedText(cursor); - Q_ASSERT(!text.isEmpty()); - QString evaText = g_mwMgr->evaluate(text); - if (text != evaText) { - qDebug() << "evaluateMagicWords" << text << evaText; - - cursor.insertText(evaText); - - if (m_editOps) { - m_editOps->setVimMode(VimMode::Insert); - } - - setTextCursor(cursor); - } -} - -void VEdit::setReadOnlyAndHighlight(bool p_readonly) -{ - setReadOnly(p_readonly); - highlightCurrentLine(); -} diff --git a/src/vedit.h b/src/vedit.h deleted file mode 100644 index 10d52c78..00000000 --- a/src/vedit.h +++ /dev/null @@ -1,295 +0,0 @@ -#ifndef VEDIT_H -#define VEDIT_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include "vconstants.h" -#include "vnotefile.h" -#include "veditconfig.h" -#include "veditor.h" - -class VEditOperations; -class QLabel; -class QTimer; -class VVim; -class QPaintEvent; -class QResizeEvent; -class QSize; -class QWidget; - -class LineNumberArea; - -class VEdit : public QTextEdit -{ - Q_OBJECT -public: - VEdit(VFile *p_file, QWidget *p_parent = 0); - virtual ~VEdit(); - virtual void beginEdit(); - virtual void endEdit(); - // Save buffer content to VFile. - virtual void saveFile(); - virtual void setModified(bool p_modified); - bool isModified() const; - virtual void reloadFile(); - - virtual bool scrollToBlock(int p_blockNumber); - - // User requests to insert an image. - virtual void insertImage(); - - // User requests to insert a link. - virtual void insertLink(); - - // Used for incremental search. - // User has enter the content to search, but does not enter the "find" button yet. - bool peekText(const QString &p_text, uint p_options, bool p_forward = true); - - // If @p_cursor is not null, set the position of @p_cursor instead of current - // cursor. - bool findText(const QString &p_text, uint p_options, bool p_forward, - QTextCursor *p_cursor = NULL, - QTextCursor::MoveMode p_moveMode = QTextCursor::MoveAnchor); - - void replaceText(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext); - void replaceTextAll(const QString &p_text, uint p_options, - const QString &p_replaceText); - - // Clear SearchedKeyword highlight. - void clearSearchedWordHighlight(); - - // Clear SearchedKeywordUnderCursor Highlight. - void clearSearchedWordUnderCursorHighlight(bool p_now = true); - - // Clear IncrementalSearchedKeyword highlight. - void clearIncrementalSearchedWordHighlight(bool p_now = true); - - VFile *getFile() const; - - VEditConfig &getConfig(); - - // Request to update Vim status. - void requestUpdateVimStatus(); - - QVariant inputMethodQuery(Qt::InputMethodQuery p_query) const Q_DECL_OVERRIDE; - - void setInputMethodEnabled(bool p_enabled); - - // Insert decoration markers or decorate selected text. - void decorateText(TextDecoration p_decoration); - - // LineNumberArea will call this to request paint itself. - void lineNumberAreaPaintEvent(QPaintEvent *p_event); - - // Scroll the content to make @p_block visible. - // If the @p_block is too long to hold in one page, just let it occupy the - // whole page. - // Will not change current cursor. - void makeBlockVisible(const QTextBlock &p_block); - - bool isBlockVisible(const QTextBlock &p_block); - - // Evaluate selected text or cursor word as magic words. - void evaluateMagicWords(); - -signals: - // Request VEditTab to save and exit edit mode. - void saveAndRead(); - - // Request VEditTab to discard and exit edit mode. - void discardAndRead(); - - // Request VEditTab to edit current note. - void editNote(); - - // Request VEditTab to save this file. - void saveNote(); - - // Emit when m_config has been updated. - void configUpdated(); - - // Emit when want to show message in status bar. - void statusMessage(const QString &p_msg); - - // Emit when Vim status updated. - void vimStatusUpdated(const VVim *p_vim); - - // Selection changed by mouse. - void selectionChangedByMouse(bool p_hasSelection); - - // Request the edit tab to close find and replace dialog. - void requestCloseFindReplaceDialog(); - - // Emit when all initialization is ready. - void ready(); - -public slots: - virtual void highlightCurrentLine(); - - // Jump to a title. - // @p_forward: jump forward or backward. - // @p_relativeLevel: 0 for the same level as current header; - // negative value for upper level; - // positive value is ignored. - // Returns true if the jump succeeded. - virtual bool jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat); - -private slots: - void labelTimerTimeout(); - void highlightSelectedWord(); - void handleSaveExitAct(); - void handleDiscardExitAct(); - void handleEditAct(); - void highlightTrailingSpace(); - void handleCursorPositionChanged(); - - // Update viewport margin to hold the line number area. - void updateLineNumberAreaMargin(); - - void updateLineNumberArea(); - - // According to the document change, try to set the block line distance height - // if affected blocks are not set. - void updateBlockLineDistanceHeight(int p_pos, int p_charsRemoved, int p_charsAdded); - -protected: - QPointer m_file; - VEditOperations *m_editOps; - - VEditConfig m_config; - - virtual void updateFontAndPalette(); - virtual void contextMenuEvent(QContextMenuEvent *p_event) Q_DECL_OVERRIDE; - - // Used to implement dragging mouse with Ctrl and left button pressed to scroll. - virtual void mousePressEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE; - virtual void mouseReleaseEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE; - virtual void mouseMoveEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE; - - virtual void resizeEvent(QResizeEvent *p_event) Q_DECL_OVERRIDE; - - // Update m_config according to VConfigManager. - void updateConfig(); - - // Called in contextMenuEvent() to modify the context menu. - virtual void alterContextMenu(QMenu *p_menu, const QList &p_actions); - - // Set read-only property and highlight current line. - void setReadOnlyAndHighlight(bool p_readonly); - -private: - QLabel *m_wrapLabel; - QTimer *m_labelTimer; - - // doHighlightExtraSelections() will highlight these selections. - // Selections are indexed by SelectionId. - QVector > m_extraSelections; - - QColor m_selectedWordColor; - QColor m_searchedWordColor; - QColor m_searchedWordCursorColor; - QColor m_incrementalSearchedWordColor; - QColor m_trailingSpaceColor; - - // Timer for extra selections highlight. - QTimer *m_highlightTimer; - - bool m_readyToScroll; - bool m_mouseMoveScrolled; - int m_oriMouseX; - int m_oriMouseY; - - // Whether enable input method. - bool m_enableInputMethod; - - LineNumberArea *m_lineNumberArea; - - void showWrapLabel(); - - // Trigger the timer to request highlight. - // If @p_now is true, stop the timer and highlight immediately. - void highlightExtraSelections(bool p_now = false); - - // Do the real work to highlight extra selections. - void doHighlightExtraSelections(); - - // Find all the occurences of @p_text. - QList findTextAll(const QString &p_text, uint p_options); - - // @p_fileter: a function to filter out highlight results. - void highlightTextAll(const QString &p_text, uint p_options, - SelectionId p_id, QTextCharFormat p_format, - void (*p_filter)(VEdit *, QList &) = NULL); - - void highlightSearchedWord(const QString &p_text, uint p_options); - - // Highlight @p_cursor as the searched keyword under cursor. - void highlightSearchedWordUnderCursor(const QTextCursor &p_cursor); - - // Highlight @p_cursor as the incremental searched keyword. - void highlightIncrementalSearchedWord(const QTextCursor &p_cursor); - - bool wordInSearchedSelection(const QString &p_text); - - // Return the first visible block. - QTextBlock firstVisibleBlock(); - - // Return the y offset of the content. - int contentOffsetY(); - - // Find @p_text in the document starting from @p_start. - // Returns true if @p_text is found and set @p_cursor to indicate - // the position. - // Will NOT change current cursor. - bool findTextHelper(const QString &p_text, uint p_options, - bool p_forward, int p_start, - bool &p_wrapped, QTextCursor &p_cursor); -}; - -class LineNumberArea : public QWidget -{ -public: - LineNumberArea(VEdit *p_editor) - : QWidget(p_editor), m_editor(p_editor), - m_document(p_editor->document()), - m_width(0), m_blockCount(-1) - { - m_digitWidth = m_editor->fontMetrics().width(QLatin1Char('1')); - m_digitHeight = m_editor->fontMetrics().height(); - } - - QSize sizeHint() const Q_DECL_OVERRIDE - { - return QSize(calculateWidth(), 0); - } - - int calculateWidth() const; - - int getDigitHeight() const - { - return m_digitHeight; - } - -protected: - void paintEvent(QPaintEvent *p_event) Q_DECL_OVERRIDE - { - m_editor->lineNumberAreaPaintEvent(p_event); - } - -private: - VEdit *m_editor; - const QTextDocument *m_document; - int m_width; - int m_blockCount; - int m_digitWidth; - int m_digitHeight; -}; - -#endif // VEDIT_H diff --git a/src/veditarea.cpp b/src/veditarea.cpp deleted file mode 100644 index 4fa50062..00000000 --- a/src/veditarea.cpp +++ /dev/null @@ -1,1087 +0,0 @@ -#include -#include "veditarea.h" -#include "veditwindow.h" -#include "vedittab.h" -#include "vnote.h" -#include "vconfigmanager.h" -#include "vfile.h" -#include "dialog/vfindreplacedialog.h" -#include "utils/vutils.h" -#include "vfilesessioninfo.h" -#include "vmainwindow.h" -#include "vcaptain.h" -#include "vfilelist.h" - -extern VConfigManager *g_config; - -extern VNote *g_vnote; - -extern VMainWindow *g_mainWin; - -VEditArea::VEditArea(QWidget *parent) - : QWidget(parent), - VNavigationMode(), - curWindowIndex(-1) -{ - setupUI(); - - insertSplitWindow(0); - setCurrentWindow(0, false); - - registerCaptainTargets(); - - - QString keySeq = g_config->getShortcutKeySequence("ActivateNextTab"); - qDebug() << "set ActivateNextTab shortcut to" << keySeq; - QShortcut *activateNextTab = new QShortcut(QKeySequence(keySeq), this); - activateNextTab->setContext(Qt::ApplicationShortcut); - connect(activateNextTab, &QShortcut::activated, - this, [this]() { - VEditWindow *win = getCurrentWindow(); - if (win) { - win->focusNextTab(true); - } - }); - - keySeq = g_config->getShortcutKeySequence("ActivatePreviousTab"); - qDebug() << "set ActivatePreviousTab shortcut to" << keySeq; - QShortcut *activatePreviousTab = new QShortcut(QKeySequence(keySeq), this); - activatePreviousTab->setContext(Qt::ApplicationShortcut); - connect(activatePreviousTab, &QShortcut::activated, - this, [this]() { - VEditWindow *win = getCurrentWindow(); - if (win) { - win->focusNextTab(false); - } - }); - - QTimer *timer = new QTimer(this); - timer->setSingleShot(false); - timer->setInterval(g_config->getFileTimerInterval()); - connect(timer, &QTimer::timeout, - this, &VEditArea::handleFileTimerTimeout); - - timer->start(); -} - -void VEditArea::setupUI() -{ - splitter = new QSplitter(this); - m_findReplace = new VFindReplaceDialog(this); - m_findReplace->setOption(FindOption::CaseSensitive, - g_config->getFindCaseSensitive()); - m_findReplace->setOption(FindOption::WholeWordOnly, - g_config->getFindWholeWordOnly()); - m_findReplace->setOption(FindOption::RegularExpression, - g_config->getFindRegularExpression()); - m_findReplace->setOption(FindOption::IncrementalSearch, - g_config->getFindIncrementalSearch()); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(splitter); - mainLayout->addWidget(m_findReplace); - mainLayout->setContentsMargins(0, 0, 0, 0); - mainLayout->setSpacing(0); - mainLayout->setStretch(0, 1); - mainLayout->setStretch(1, 0); - - setLayout(mainLayout); - - connect(m_findReplace, &VFindReplaceDialog::findTextChanged, - this, &VEditArea::handleFindTextChanged); - connect(m_findReplace, &VFindReplaceDialog::findOptionChanged, - this, &VEditArea::handleFindOptionChanged); - connect(m_findReplace, SIGNAL(findNext(const QString &, uint, bool)), - this, SLOT(handleFindNext(const QString &, uint, bool))); - connect(m_findReplace, - SIGNAL(replace(const QString &, uint, const QString &, bool)), - this, - SLOT(handleReplace(const QString &, uint, const QString &, bool))); - connect(m_findReplace, - SIGNAL(replaceAll(const QString &, uint, const QString &)), - this, - SLOT(handleReplaceAll(const QString &, uint, const QString &))); - connect(m_findReplace, &VFindReplaceDialog::dialogClosed, - this, &VEditArea::handleFindDialogClosed); - m_findReplace->hide(); - - // Shortcut Ctrl+Shift+T to open last closed file. - QString keySeq = g_config->getShortcutKeySequence("LastClosedFile"); - qDebug() << "set LastClosedFile shortcut to" << keySeq; - QShortcut *lastClosedFileShortcut = new QShortcut(QKeySequence(keySeq), this); - lastClosedFileShortcut->setContext(Qt::ApplicationShortcut); - connect(lastClosedFileShortcut, &QShortcut::activated, - this, [this]() { - if (!m_lastClosedFiles.isEmpty()) { - const VFileSessionInfo &file = m_lastClosedFiles.top(); - QVector files(1, file); - m_lastClosedFiles.pop(); - - openFiles(files); - } - }); -} - -void VEditArea::insertSplitWindow(int idx) -{ - VEditWindow *win = new VEditWindow(this); - splitter->insertWidget(idx, win); - connect(win, &VEditWindow::tabStatusUpdated, - this, &VEditArea::handleWindowTabStatusUpdated); - connect(win, &VEditWindow::requestSplitWindow, - this, &VEditArea::splitWindow); - connect(win, &VEditWindow::requestRemoveSplit, - this, &VEditArea::handleRemoveSplitRequest); - connect(win, &VEditWindow::getFocused, - this, &VEditArea::handleWindowFocused); - connect(win, &VEditWindow::outlineChanged, - this, &VEditArea::handleWindowOutlineChanged); - connect(win, &VEditWindow::currentHeaderChanged, - this, &VEditArea::handleWindowCurrentHeaderChanged); - connect(win, &VEditWindow::statusMessage, - this, &VEditArea::handleWindowStatusMessage); - connect(win, &VEditWindow::vimStatusUpdated, - this, &VEditArea::handleWindowVimStatusUpdated); -} - -void VEditArea::handleWindowTabStatusUpdated(const VEditTabInfo &p_info) -{ - if (splitter->widget(curWindowIndex) == sender()) { - emit tabStatusUpdated(p_info); - } -} - -void VEditArea::handleWindowStatusMessage(const QString &p_msg) -{ - if (splitter->widget(curWindowIndex) == sender()) { - emit statusMessage(p_msg); - } -} - -void VEditArea::handleWindowVimStatusUpdated(const VVim *p_vim) -{ - if (splitter->widget(curWindowIndex) == sender()) { - emit vimStatusUpdated(p_vim); - } -} - -void VEditArea::removeSplitWindow(VEditWindow *win) -{ - if (!win) { - return; - } - - win->hide(); - win->setParent(this); - disconnect(win, 0, this, 0); - // Should be deleted later - win->deleteLater(); -} - -VEditTab *VEditArea::openFile(VFile *p_file, OpenFileMode p_mode, bool p_forceMode) -{ - if (!p_file) { - return NULL; - } - - // If it is DocType::Unknown, open it using system default method. - if (p_file->getDocType() == DocType::Unknown) { - QUrl url = QUrl::fromLocalFile(p_file->fetchPath()); - QDesktopServices::openUrl(url); - return NULL; - } - - // Find if it has been opened already - int winIdx, tabIdx; - bool existFile = false; - bool setFocus = false; - auto tabs = findTabsByFile(p_file); - if (!tabs.empty()) { - // Current window first - winIdx = tabs[0].first; - tabIdx = tabs[0].second; - for (int i = 0; i < tabs.size(); ++i) { - if (tabs[i].first == curWindowIndex) { - winIdx = tabs[i].first; - tabIdx = tabs[i].second; - break; - } - } - - setFocus = true; - existFile = true; - goto out; - } - - // Open it in current window - if (curWindowIndex == -1) { - // insert a new split - insertSplitWindow(0); - curWindowIndex = 0; - } - - winIdx = curWindowIndex; - tabIdx = openFileInWindow(winIdx, p_file, p_mode); - -out: - VEditTab *tab = getTab(winIdx, tabIdx); - - setCurrentTab(winIdx, tabIdx, setFocus); - - if (existFile && p_forceMode) { - if (p_mode == OpenFileMode::Read) { - readFile(); - } else if (p_mode == OpenFileMode::Edit) { - editFile(); - } - } - - return tab; -} - -QVector > VEditArea::findTabsByFile(const VFile *p_file) -{ - QVector > tabs; - int nrWin = splitter->count(); - for (int winIdx = 0; winIdx < nrWin; ++winIdx) { - VEditWindow *win = getWindow(winIdx); - int tabIdx = win->findTabByFile(p_file); - if (tabIdx != -1) { - QPair match; - match.first = winIdx; - match.second = tabIdx; - tabs.append(match); - } - } - return tabs; -} - -int VEditArea::openFileInWindow(int windowIndex, VFile *p_file, OpenFileMode p_mode) -{ - Q_ASSERT(windowIndex < splitter->count()); - VEditWindow *win = getWindow(windowIndex); - return win->openFile(p_file, p_mode); -} - -void VEditArea::setCurrentTab(int windowIndex, int tabIndex, bool setFocus) -{ - VEditWindow *win = getWindow(windowIndex); - win->setCurrentIndex(tabIndex); - - setCurrentWindow(windowIndex, setFocus); -} - -void VEditArea::setCurrentWindow(int windowIndex, bool setFocus) -{ - int nrWin = splitter->count(); - curWindowIndex = windowIndex; - - for (int i = 0; i < nrWin; ++i) { - getWindow(i)->setCurrentWindow(false); - } - if (curWindowIndex > -1) { - getWindow(curWindowIndex)->setCurrentWindow(true); - if (setFocus) { - getWindow(curWindowIndex)->focusWindow(); - } - } - // Update status - updateWindowStatus(); -} - -void VEditArea::updateWindowStatus() -{ - if (curWindowIndex == -1) { - Q_ASSERT(splitter->count() == 0); - - emit tabStatusUpdated(VEditTabInfo()); - emit outlineChanged(VTableOfContent()); - emit currentHeaderChanged(VHeaderPointer()); - return; - } - - VEditWindow *win = getWindow(curWindowIndex); - win->updateTabStatus(); -} - -bool VEditArea::closeFile(const VFile *p_file, bool p_forced) -{ - if (!p_file) { - return true; - } - bool ret = false; - int i = 0; - while (i < splitter->count()) { - VEditWindow *win = getWindow(i); - int nrWin = splitter->count(); - ret = ret || win->closeFile(p_file, p_forced); - if (nrWin == splitter->count()) { - ++i; - } - } - updateWindowStatus(); - return ret; -} - -bool VEditArea::closeFile(const VDirectory *p_dir, bool p_forced) -{ - if (!p_dir) { - return true; - } - int i = 0; - while (i < splitter->count()) { - VEditWindow *win = getWindow(i); - if (!p_forced) { - setCurrentWindow(i, false); - } - int nrWin = splitter->count(); - if (!win->closeFile(p_dir, p_forced)) { - return false; - } - // win may be removed after closeFile() - if (nrWin == splitter->count()) { - ++i; - } - } - updateWindowStatus(); - return true; -} - -bool VEditArea::closeFile(const VNotebook *p_notebook, bool p_forced) -{ - if (!p_notebook) { - return true; - } - int i = 0; - while (i < splitter->count()) { - VEditWindow *win = getWindow(i); - if (!p_forced) { - setCurrentWindow(i, false); - } - int nrWin = splitter->count(); - if (!win->closeFile(p_notebook, p_forced)) { - return false; - } - // win may be removed after closeFile() - if (nrWin == splitter->count()) { - ++i; - } - } - updateWindowStatus(); - return true; -} - -bool VEditArea::closeAllFiles(bool p_forced) -{ - int i = 0; - while (i < splitter->count()) { - VEditWindow *win = getWindow(i); - if (!p_forced) { - setCurrentWindow(i, false); - } - int nrWin = splitter->count(); - if (!win->closeAllFiles(p_forced)) { - return false; - } - if (nrWin == splitter->count()) { - ++i; - } - } - updateWindowStatus(); - return true; -} - -void VEditArea::editFile() -{ - VEditWindow *win = getWindow(curWindowIndex); - win->editFile(); -} - -void VEditArea::saveFile() -{ - VEditWindow *win = getWindow(curWindowIndex); - win->saveFile(); -} - -void VEditArea::readFile() -{ - VEditWindow *win = getWindow(curWindowIndex); - win->readFile(); -} - -void VEditArea::saveAndReadFile() -{ - VEditWindow *win = getWindow(curWindowIndex); - win->saveAndReadFile(); -} - -void VEditArea::splitWindow(VEditWindow *p_window, bool p_right) -{ - if (!p_window) { - return; - } - - int idx = splitter->indexOf(p_window); - Q_ASSERT(idx > -1); - if (p_right) { - ++idx; - } else { - --idx; - if (idx < 0) { - idx = 0; - } - } - - insertSplitWindow(idx); - setCurrentWindow(idx, true); -} - -void VEditArea::splitCurrentWindow() -{ - if (curWindowIndex > -1) { - splitWindow(getWindow(curWindowIndex)); - } -} - -void VEditArea::handleRemoveSplitRequest(VEditWindow *curWindow) -{ - if (!curWindow || splitter->count() <= 1) { - return; - } - int idx = splitter->indexOf(curWindow); - - // curWindow will be deleted later - removeSplitWindow(curWindow); - - if (idx >= splitter->count()) { - idx = splitter->count() - 1; - } - setCurrentWindow(idx, true); -} - -void VEditArea::removeCurrentWindow() -{ - if (curWindowIndex > -1) { - handleRemoveSplitRequest(getWindow(curWindowIndex)); - } -} - -void VEditArea::mousePressEvent(QMouseEvent *event) -{ - QPoint pos = event->pos(); - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - VEditWindow *win = getWindow(i); - if (win->geometry().contains(pos, true)) { - setCurrentWindow(i, true); - break; - } - } - QWidget::mousePressEvent(event); -} - -void VEditArea::handleWindowFocused() -{ - QObject *winObject = sender(); - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - if (splitter->widget(i) == winObject) { - setCurrentWindow(i, false); - break; - } - } -} - -void VEditArea::handleWindowOutlineChanged(const VTableOfContent &p_outline) -{ - QObject *winObject = sender(); - if (splitter->widget(curWindowIndex) == winObject) { - emit outlineChanged(p_outline); - } -} - -void VEditArea::handleWindowCurrentHeaderChanged(const VHeaderPointer &p_header) -{ - QObject *winObject = sender(); - if (splitter->widget(curWindowIndex) == winObject) { - emit currentHeaderChanged(p_header); - } -} - -void VEditArea::scrollToHeader(const VHeaderPointer &p_header) -{ - VEditWindow *win = getCurrentWindow(); - if (win) { - win->scrollToHeader(p_header); - } -} - -bool VEditArea::isFileOpened(const VFile *p_file) -{ - return !findTabsByFile(p_file).isEmpty(); -} - -void VEditArea::handleFileUpdated(const VFile *p_file, UpdateAction p_act) -{ - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - getWindow(i)->updateFileInfo(p_file, p_act); - } -} - -void VEditArea::handleDirectoryUpdated(const VDirectory *p_dir, UpdateAction p_act) -{ - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - getWindow(i)->updateDirectoryInfo(p_dir, p_act); - } -} - -void VEditArea::handleNotebookUpdated(const VNotebook *p_notebook) -{ - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - getWindow(i)->updateNotebookInfo(p_notebook); - } -} - -VEditTab *VEditArea::getCurrentTab() const -{ - if (curWindowIndex == -1) { - return NULL; - } - - VEditWindow *win = getWindow(curWindowIndex); - return win->getCurrentTab(); -} - -VEditTab *VEditArea::getTab(int p_winIdx, int p_tabIdx) const -{ - VEditWindow *win = getWindow(p_winIdx); - if (!win) { - return NULL; - } - - return win->getTab(p_tabIdx); -} - -QVector VEditArea::getAllTabsInfo() const -{ - QVector tabs; - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - tabs.append(getWindow(i)->getAllTabsInfo()); - } - - return tabs; -} - -int VEditArea::windowIndex(const VEditWindow *p_window) const -{ - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - if (p_window == getWindow(i)) { - return i; - } - } - return -1; -} - -void VEditArea::moveTab(QWidget *p_widget, int p_fromIdx, int p_toIdx) -{ - int nrWin = splitter->count(); - if (!p_widget || p_fromIdx < 0 || p_fromIdx >= nrWin - || p_toIdx < 0 || p_toIdx >= nrWin) { - return; - } - qDebug() << "move widget" << p_widget << "from" << p_fromIdx << "to" << p_toIdx; - if (!getWindow(p_toIdx)->addEditTab(p_widget)) { - delete p_widget; - } -} - -// Only propogate the search in the IncrementalSearch case. -void VEditArea::handleFindTextChanged(const QString &p_text, uint p_options) -{ - VEditTab *tab = getCurrentTab(); - if (tab) { - if (p_options & FindOption::IncrementalSearch) { - tab->findText(p_text, p_options, true); - } - } -} - -void VEditArea::handleFindOptionChanged(uint p_options) -{ - qDebug() << "find option changed" << p_options; - g_config->setFindCaseSensitive(p_options & FindOption::CaseSensitive); - g_config->setFindWholeWordOnly(p_options & FindOption::WholeWordOnly); - g_config->setFindRegularExpression(p_options & FindOption::RegularExpression); - g_config->setFindIncrementalSearch(p_options & FindOption::IncrementalSearch); -} - -void VEditArea::handleFindNext(const QString &p_text, uint p_options, - bool p_forward) -{ - qDebug() << "find next" << p_text << p_options << p_forward; - VEditTab *tab = getCurrentTab(); - if (tab) { - tab->findText(p_text, p_options, false, p_forward); - } -} - -void VEditArea::handleReplace(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext) -{ - qDebug() << "replace" << p_text << p_options << "with" << p_replaceText - << p_findNext; - VEditTab *tab = getCurrentTab(); - if (tab) { - tab->replaceText(p_text, p_options, p_replaceText, p_findNext); - } -} - -void VEditArea::handleReplaceAll(const QString &p_text, uint p_options, - const QString &p_replaceText) -{ - qDebug() << "replace all" << p_text << p_options << "with" << p_replaceText; - VEditTab *tab = getCurrentTab(); - if (tab) { - tab->replaceTextAll(p_text, p_options, p_replaceText); - } -} - -// Let VEditArea get focus after VFindReplaceDialog is closed. -void VEditArea::handleFindDialogClosed() -{ - if (curWindowIndex == -1) { - setFocus(); - } else { - getWindow(curWindowIndex)->focusWindow(); - } - - // Clear all the search highlight. - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - getWindow(i)->clearSearchedWordHighlight(); - } -} - -QString VEditArea::getSelectedText() -{ - VEditTab *tab = getCurrentTab(); - if (tab) { - return tab->getSelectedText(); - } else { - return QString(); - } -} - -int VEditArea::focusNextWindow(int p_biaIdx) -{ - if (p_biaIdx == 0) { - return curWindowIndex; - } - int newIdx = curWindowIndex + p_biaIdx; - if (newIdx < 0) { - newIdx = 0; - } else if (newIdx >= splitter->count()) { - newIdx = splitter->count() - 1; - } - if (newIdx >= 0 && newIdx < splitter->count()) { - setCurrentWindow(newIdx, true); - } else { - newIdx = -1; - } - return newIdx; -} - -void VEditArea::moveCurrentTabOneSplit(bool p_right) -{ - getWindow(curWindowIndex)->moveCurrentTabOneSplit(p_right); -} - -VEditWindow *VEditArea::getCurrentWindow() const -{ - if (curWindowIndex < 0) { - return NULL; - } - - return getWindow(curWindowIndex); -} - -void VEditArea::registerNavigation(QChar p_majorKey) -{ - m_majorKey = p_majorKey; - V_ASSERT(m_keyMap.empty()); - V_ASSERT(m_naviLabels.empty()); -} - -void VEditArea::showNavigation() -{ - // Clean up. - m_keyMap.clear(); - for (auto label : m_naviLabels) { - delete label; - } - m_naviLabels.clear(); - - if (!isVisible()) { - return; - } - - // Generate labels for VEditWindow. - for (int i = 0; i < 26 && i < splitter->count(); ++i) { - QChar key('a' + i); - m_keyMap[key] = getWindow(i); - - QString str = QString(m_majorKey) + key; - QLabel *label = new QLabel(str, this); - label->setStyleSheet(g_vnote->getNavigationLabelStyle(str)); - label->move(getWindow(i)->geometry().topLeft()); - label->show(); - m_naviLabels.append(label); - } -} - -void VEditArea::hideNavigation() -{ - m_keyMap.clear(); - for (auto label : m_naviLabels) { - delete label; - } - m_naviLabels.clear(); -} - -bool VEditArea::handleKeyNavigation(int p_key, bool &p_succeed) -{ - static bool secondKey = false; - bool ret = false; - p_succeed = false; - QChar keyChar = VUtils::keyToChar(p_key); - if (secondKey && !keyChar.isNull()) { - secondKey = false; - p_succeed = true; - ret = true; - auto it = m_keyMap.find(keyChar); - if (it != m_keyMap.end()) { - setCurrentWindow(splitter->indexOf(static_cast(it.value())), - true); - } - } else if (keyChar == m_majorKey) { - // Major key pressed. - // Need second key if m_keyMap is not empty. - if (m_keyMap.isEmpty()) { - p_succeed = true; - } else { - secondKey = true; - } - ret = true; - } - return ret; -} - -int VEditArea::openFiles(const QVector &p_files) -{ - int nrOpened = 0; - for (auto const & info : p_files) { - QString filePath = VUtils::validFilePathToOpen(info.m_file); - if (filePath.isEmpty()) { - continue; - } - - VFile *file = g_vnote->getFile(filePath); - if (!file) { - continue; - } - - VEditTab *tab = openFile(file, info.m_mode, true); - ++nrOpened; - - VEditTabInfo tabInfo; - tabInfo.m_editTab = tab; - info.toEditTabInfo(&tabInfo); - - tab->tryRestoreFromTabInfo(tabInfo); - } - - return nrOpened; -} - -void VEditArea::registerCaptainTargets() -{ - using namespace std::placeholders; - - VCaptain *captain = g_mainWin->getCaptain(); - - captain->registerCaptainTarget(tr("ActivateTab1"), - g_config->getCaptainShortcutKeySequence("ActivateTab1"), - this, - std::bind(activateTabByCaptain, _1, _2, 1)); - captain->registerCaptainTarget(tr("ActivateTab2"), - g_config->getCaptainShortcutKeySequence("ActivateTab2"), - this, - std::bind(activateTabByCaptain, _1, _2, 2)); - captain->registerCaptainTarget(tr("ActivateTab3"), - g_config->getCaptainShortcutKeySequence("ActivateTab3"), - this, - std::bind(activateTabByCaptain, _1, _2, 3)); - captain->registerCaptainTarget(tr("ActivateTab4"), - g_config->getCaptainShortcutKeySequence("ActivateTab4"), - this, - std::bind(activateTabByCaptain, _1, _2, 4)); - captain->registerCaptainTarget(tr("ActivateTab5"), - g_config->getCaptainShortcutKeySequence("ActivateTab5"), - this, - std::bind(activateTabByCaptain, _1, _2, 5)); - captain->registerCaptainTarget(tr("ActivateTab6"), - g_config->getCaptainShortcutKeySequence("ActivateTab6"), - this, - std::bind(activateTabByCaptain, _1, _2, 6)); - captain->registerCaptainTarget(tr("ActivateTab7"), - g_config->getCaptainShortcutKeySequence("ActivateTab7"), - this, - std::bind(activateTabByCaptain, _1, _2, 7)); - captain->registerCaptainTarget(tr("ActivateTab8"), - g_config->getCaptainShortcutKeySequence("ActivateTab8"), - this, - std::bind(activateTabByCaptain, _1, _2, 8)); - captain->registerCaptainTarget(tr("ActivateTab9"), - g_config->getCaptainShortcutKeySequence("ActivateTab9"), - this, - std::bind(activateTabByCaptain, _1, _2, 9)); - captain->registerCaptainTarget(tr("AlternateTab"), - g_config->getCaptainShortcutKeySequence("AlternateTab"), - this, - alternateTabByCaptain); - captain->registerCaptainTarget(tr("OpenedFileList"), - g_config->getCaptainShortcutKeySequence("OpenedFileList"), - this, - showOpenedFileListByCaptain); - captain->registerCaptainTarget(tr("ActivateSplitLeft"), - g_config->getCaptainShortcutKeySequence("ActivateSplitLeft"), - this, - activateSplitLeftByCaptain); - captain->registerCaptainTarget(tr("ActivateSplitRight"), - g_config->getCaptainShortcutKeySequence("ActivateSplitRight"), - this, - activateSplitRightByCaptain); - captain->registerCaptainTarget(tr("MoveTabSplitLeft"), - g_config->getCaptainShortcutKeySequence("MoveTabSplitLeft"), - this, - moveTabSplitLeftByCaptain); - captain->registerCaptainTarget(tr("MoveTabSplitRight"), - g_config->getCaptainShortcutKeySequence("MoveTabSplitRight"), - this, - moveTabSplitRightByCaptain); - captain->registerCaptainTarget(tr("ActivateNextTab"), - g_config->getCaptainShortcutKeySequence("ActivateNextTab"), - this, - activateNextTabByCaptain); - captain->registerCaptainTarget(tr("ActivatePreviousTab"), - g_config->getCaptainShortcutKeySequence("ActivatePreviousTab"), - this, - activatePreviousTabByCaptain); - captain->registerCaptainTarget(tr("VerticalSplit"), - g_config->getCaptainShortcutKeySequence("VerticalSplit"), - this, - verticalSplitByCaptain); - captain->registerCaptainTarget(tr("RemoveSplit"), - g_config->getCaptainShortcutKeySequence("RemoveSplit"), - this, - removeSplitByCaptain); - captain->registerCaptainTarget(tr("MagicWord"), - g_config->getCaptainShortcutKeySequence("MagicWord"), - this, - evaluateMagicWordsByCaptain); - captain->registerCaptainTarget(tr("ApplySnippet"), - g_config->getCaptainShortcutKeySequence("ApplySnippet"), - this, - applySnippetByCaptain); -} - -bool VEditArea::activateTabByCaptain(void *p_target, void *p_data, int p_idx) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - VEditWindow *win = obj->getCurrentWindow(); - if (win) { - if (win->activateTab(p_idx)) { - return false; - } - } - - return true; -} - -bool VEditArea::alternateTabByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - VEditWindow *win = obj->getCurrentWindow(); - if (win) { - if (win->alternateTab()) { - return false; - } - } - - return true; -} - -bool VEditArea::showOpenedFileListByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - VEditWindow *win = obj->getCurrentWindow(); - if (win) { - if (win->showOpenedFileList()) { - return false; - } - } - - return true; -} - -bool VEditArea::activateSplitLeftByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - if (obj->focusNextWindow(-1) > -1) { - return false; - } - - return true; -} - -bool VEditArea::activateSplitRightByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - if (obj->focusNextWindow(1) > -1) { - return false; - } - - return true; -} - -bool VEditArea::moveTabSplitLeftByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - obj->moveCurrentTabOneSplit(false); - return true; -} - -bool VEditArea::moveTabSplitRightByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - obj->moveCurrentTabOneSplit(true); - return true; -} - -bool VEditArea::activateNextTabByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - VEditWindow *win = obj->getCurrentWindow(); - if (win) { - win->focusNextTab(true); - } - - return true; -} - -bool VEditArea::activatePreviousTabByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - VEditWindow *win = obj->getCurrentWindow(); - if (win) { - win->focusNextTab(false); - return false; - } - - return true; -} - -bool VEditArea::verticalSplitByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - obj->splitCurrentWindow(); - return false; -} - -bool VEditArea::removeSplitByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - obj->removeCurrentWindow(); - - QWidget *nextFocus = obj->getCurrentTab(); - if (nextFocus) { - nextFocus->setFocus(); - } else { - g_mainWin->getFileList()->setFocus(); - } - - return false; -} - -bool VEditArea::evaluateMagicWordsByCaptain(void *p_target, void *p_data) -{ - VEditArea *obj = static_cast(p_target); - CaptainData *data = static_cast(p_data); - - VEditTab *tab = obj->getCurrentTab(); - if (tab - && (data->m_focusWidgetBeforeCaptain == tab - || tab->isAncestorOf(data->m_focusWidgetBeforeCaptain))) { - tab->evaluateMagicWords(); - } - - return true; -} - -bool VEditArea::applySnippetByCaptain(void *p_target, void *p_data) -{ - VEditArea *obj = static_cast(p_target); - CaptainData *data = static_cast(p_data); - - VEditTab *tab = obj->getCurrentTab(); - if (tab - && (data->m_focusWidgetBeforeCaptain == tab - || tab->isAncestorOf(data->m_focusWidgetBeforeCaptain))) { - tab->applySnippet(); - } - - return true; -} - -void VEditArea::recordClosedFile(const VFileSessionInfo &p_file) -{ - for (auto it = m_lastClosedFiles.begin(); it != m_lastClosedFiles.end(); ++it) { - if (it->m_file == p_file.m_file) { - // Remove it. - m_lastClosedFiles.erase(it); - break; - } - } - - m_lastClosedFiles.push(p_file); - qDebug() << "pushed closed file" << p_file.m_file; -} - -void VEditArea::handleFileTimerTimeout() -{ - checkFileChangeOutside(); -} - -void VEditArea::checkFileChangeOutside() -{ - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - getWindow(i)->checkFileChangeOutside(); - } -} diff --git a/src/veditarea.h b/src/veditarea.h deleted file mode 100644 index c41501c6..00000000 --- a/src/veditarea.h +++ /dev/null @@ -1,237 +0,0 @@ -#ifndef VEDITAREA_H -#define VEDITAREA_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "vnotebook.h" -#include "veditwindow.h" -#include "vnavigationmode.h" -#include "vfilesessioninfo.h" - -class VFile; -class VDirectory; -class VFindReplaceDialog; -class QLabel; -class VVim; - -class VEditArea : public QWidget, public VNavigationMode -{ - Q_OBJECT -public: - explicit VEditArea(QWidget *parent = 0); - - // Whether @p_file has been opened in edit area. - bool isFileOpened(const VFile *p_file); - - bool closeAllFiles(bool p_forced); - bool closeFile(const VFile *p_file, bool p_forced); - bool closeFile(const VDirectory *p_dir, bool p_forced); - bool closeFile(const VNotebook *p_notebook, bool p_forced); - - // Return current edit window. - VEditWindow *getCurrentWindow() const; - - // Return current edit tab. - VEditTab *getCurrentTab() const; - - // Return the @p_tabIdx tab in the @p_winIdx window. - VEditTab *getTab(int p_winIdx, int p_tabIdx) const; - - // Return VEditTabInfo of all edit tabs. - QVector getAllTabsInfo() const; - - // Return the count of VEditWindow. - int windowCount() const; - - // Returns the index of @p_window. - int windowIndex(const VEditWindow *p_window) const; - // Move tab widget @p_widget from window @p_fromIdx to @p_toIdx. - // @p_widget has been removed from the original window. - // If fail, just delete the p_widget. - void moveTab(QWidget *p_widget, int p_fromIdx, int p_toIdx); - - VFindReplaceDialog *getFindReplaceDialog() const; - - // Return selected text of current edit tab. - QString getSelectedText(); - void splitCurrentWindow(); - void removeCurrentWindow(); - // Focus next window (curWindowIndex + p_biaIdx). - // Return the new current window index, otherwise, return -1. - int focusNextWindow(int p_biaIdx); - void moveCurrentTabOneSplit(bool p_right); - - // Implementations for VNavigationMode. - void registerNavigation(QChar p_majorKey) Q_DECL_OVERRIDE; - void showNavigation() Q_DECL_OVERRIDE; - void hideNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - - // Open files @p_files. - int openFiles(const QVector &p_files); - - // Record a closed file in the stack. - void recordClosedFile(const VFileSessionInfo &p_file); - -signals: - // Emit when current window's tab status updated. - void tabStatusUpdated(const VEditTabInfo &p_info); - - // Emit when current window's tab's outline changed. - void outlineChanged(const VTableOfContent &p_outline); - - // Emit when current window's tab's current header changed. - void currentHeaderChanged(const VHeaderPointer &p_header); - - // Emit when want to show message in status bar. - void statusMessage(const QString &p_msg); - - // Emit when Vim status updated. - void vimStatusUpdated(const VVim *p_vim); - -protected: - void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - -public slots: - // Open @p_file in mode @p_mode. - // If @p_file has already been opened, change its mode to @p_mode only if - // @p_forceMode is true. - // A given file can be opened in multiple split windows. A given file could be - // opened at most in one tab inside a window. - VEditTab *openFile(VFile *p_file, OpenFileMode p_mode, bool p_forceMode = false); - - void editFile(); - void saveFile(); - void readFile(); - void saveAndReadFile(); - - // Scroll current tab to @p_header. - void scrollToHeader(const VHeaderPointer &p_header); - - void handleFileUpdated(const VFile *p_file, UpdateAction p_act); - - void handleDirectoryUpdated(const VDirectory *p_dir, UpdateAction p_act); - - void handleNotebookUpdated(const VNotebook *p_notebook); - -private slots: - // Split @curWindow via inserting a new window around it. - // @p_right: insert the new window on the right side. - void splitWindow(VEditWindow *p_window, bool p_right = true); - - void handleRemoveSplitRequest(VEditWindow *curWindow); - void handleWindowFocused(); - - void handleWindowOutlineChanged(const VTableOfContent &p_outline); - - void handleWindowCurrentHeaderChanged(const VHeaderPointer &p_header); - - void handleFindTextChanged(const QString &p_text, uint p_options); - void handleFindOptionChanged(uint p_options); - void handleFindNext(const QString &p_text, uint p_options, bool p_forward); - void handleReplace(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext); - void handleReplaceAll(const QString &p_text, uint p_options, - const QString &p_replaceText); - void handleFindDialogClosed(); - - // Hanle the status update of current tab within a VEditWindow. - void handleWindowTabStatusUpdated(const VEditTabInfo &p_info); - - // Handle the statusMessage signal of VEditWindow. - void handleWindowStatusMessage(const QString &p_msg); - - // Handle the vimStatusUpdated signal of VEditWindow. - void handleWindowVimStatusUpdated(const VVim *p_vim); - - // Handle the timeout signal of file timer. - void handleFileTimerTimeout(); - -private: - void setupUI(); - QVector > findTabsByFile(const VFile *p_file); - int openFileInWindow(int windowIndex, VFile *p_file, OpenFileMode p_mode); - void setCurrentTab(int windowIndex, int tabIndex, bool setFocus); - void setCurrentWindow(int windowIndex, bool setFocus); - - VEditWindow *getWindow(int windowIndex) const; - - void insertSplitWindow(int idx); - void removeSplitWindow(VEditWindow *win); - - // Update status of current window. - void updateWindowStatus(); - - // Init targets for Captain mode. - void registerCaptainTargets(); - - // Check whether opened files have been changed outside. - void checkFileChangeOutside(); - - // Captain mode functions. - - // Activate tab @p_idx. - static bool activateTabByCaptain(void *p_target, void *p_data, int p_idx); - - static bool alternateTabByCaptain(void *p_target, void *p_data); - - static bool showOpenedFileListByCaptain(void *p_target, void *p_data); - - static bool activateSplitLeftByCaptain(void *p_target, void *p_data); - - static bool activateSplitRightByCaptain(void *p_target, void *p_data); - - static bool moveTabSplitLeftByCaptain(void *p_target, void *p_data); - - static bool moveTabSplitRightByCaptain(void *p_target, void *p_data); - - static bool activateNextTabByCaptain(void *p_target, void *p_data); - - static bool activatePreviousTabByCaptain(void *p_target, void *p_data); - - static bool verticalSplitByCaptain(void *p_target, void *p_data); - - static bool removeSplitByCaptain(void *p_target, void *p_data); - - // Evaluate selected text or the word on cursor as magic words. - static bool evaluateMagicWordsByCaptain(void *p_target, void *p_data); - - // Prompt for user to apply a snippet. - static bool applySnippetByCaptain(void *p_target, void *p_data); - - // End Captain mode functions. - - int curWindowIndex; - - // Splitter holding multiple split windows - QSplitter *splitter; - VFindReplaceDialog *m_findReplace; - - // Last closed files stack. - QStack m_lastClosedFiles; -}; - -inline VEditWindow* VEditArea::getWindow(int windowIndex) const -{ - Q_ASSERT(windowIndex < splitter->count()); - return dynamic_cast(splitter->widget(windowIndex)); -} - -inline int VEditArea::windowCount() const -{ - return splitter->count(); -} - -inline VFindReplaceDialog *VEditArea::getFindReplaceDialog() const -{ - return m_findReplace; -} - -#endif // VEDITAREA_H diff --git a/src/veditconfig.cpp b/src/veditconfig.cpp deleted file mode 100644 index 9866d7fa..00000000 --- a/src/veditconfig.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "veditconfig.h" - -#include "vconfigmanager.h" -#include "utils/vutils.h" - -extern VConfigManager *g_config; - -void VEditConfig::init(const QFontMetrics &p_metric, - bool p_enableHeadingSequence) -{ - update(p_metric); - - // Init configs that do not support update later. - m_enableVimMode = g_config->getEnableVimMode(); - - if (g_config->getLineDistanceHeight() <= 0) { - m_lineDistanceHeight = 0; - } else { - m_lineDistanceHeight = g_config->getLineDistanceHeight() * VUtils::calculateScaleFactor(); - } - - m_highlightWholeBlock = m_enableVimMode; - - m_enableHeadingSequence = p_enableHeadingSequence; -} - -void VEditConfig::update(const QFontMetrics &p_metric) -{ - if (g_config->getTabStopWidth() > 0) { - m_tabStopWidth = g_config->getTabStopWidth() * p_metric.width(' '); - } else { - m_tabStopWidth = 0; - } - - m_expandTab = g_config->getIsExpandTab(); - - if (m_expandTab && (g_config->getTabStopWidth() > 0)) { - m_tabSpaces = QString(g_config->getTabStopWidth(), ' '); - } else { - m_tabSpaces = "\t"; - } - - m_cursorLineBg = QColor(g_config->getEditorCurrentLineBg()); -} diff --git a/src/veditconfig.h b/src/veditconfig.h deleted file mode 100644 index af1803b0..00000000 --- a/src/veditconfig.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef VEDITCONFIG_H -#define VEDITCONFIG_H - -#include -#include -#include - - -class VEditConfig { -public: - VEditConfig() : m_tabStopWidth(0), - m_tabSpaces("\t"), - m_enableVimMode(false), - m_highlightWholeBlock(false), - m_lineDistanceHeight(0), - m_enableHeadingSequence(false) - {} - - void init(const QFontMetrics &p_metric, - bool p_enableHeadingSequence); - - // Only update those configs which could be updated online. - void update(const QFontMetrics &p_metric); - - // Width in pixels. - int m_tabStopWidth; - - bool m_expandTab; - - // The literal string for Tab. It is spaces if Tab is expanded. - QString m_tabSpaces; - - bool m_enableVimMode; - - // The background color of cursor line. - QColor m_cursorLineBg; - - // Whether highlight a visual line or a whole block. - bool m_highlightWholeBlock; - - // Line distance height in pixels. - int m_lineDistanceHeight; - - // Whether enable auto heading sequence. - bool m_enableHeadingSequence; -}; - -#endif // VEDITCONFIG_H diff --git a/src/veditoperations.cpp b/src/veditoperations.cpp deleted file mode 100644 index e36a236a..00000000 --- a/src/veditoperations.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include -#include "veditor.h" -#include "veditoperations.h" -#include "vconfigmanager.h" -#include "utils/vutils.h" - -extern VConfigManager *g_config; - -VEditOperations::VEditOperations(VEditor *p_editor, VFile *p_file) - : QObject(p_editor->getEditor()), - m_editor(p_editor), - m_file(p_file), - m_editConfig(&p_editor->getConfig()), - m_vim(NULL) -{ - connect(m_editor->object(), &VEditorObject::configUpdated, - this, &VEditOperations::handleEditConfigUpdated); - - if (m_editConfig->m_enableVimMode) { - m_vim = new VVim(m_editor); - - connect(m_vim, &VVim::modeChanged, - this, &VEditOperations::handleVimModeChanged); - connect(m_vim, &VVim::vimMessage, - this, &VEditOperations::statusMessage); - connect(m_vim, &VVim::vimStatusUpdated, - this, &VEditOperations::vimStatusUpdated); - } -} - -void VEditOperations::insertTextAtCurPos(const QString &p_text) -{ - m_editor->insertPlainTextW(p_text); -} - -VEditOperations::~VEditOperations() -{ -} - -void VEditOperations::updateCursorLineBg() -{ - if (m_editConfig->m_enableVimMode) { - switch (m_vim->getMode()) { - case VimMode::Normal: - m_editConfig->m_cursorLineBg = QColor(g_config->getEditorVimNormalBg()); - break; - - case VimMode::Insert: - m_editConfig->m_cursorLineBg = QColor(g_config->getEditorVimInsertBg()); - break; - - case VimMode::Visual: - case VimMode::VisualLine: - m_editConfig->m_cursorLineBg = QColor(g_config->getEditorVimVisualBg()); - break; - - case VimMode::Replace: - m_editConfig->m_cursorLineBg = QColor(g_config->getEditorVimReplaceBg()); - break; - - default: - V_ASSERT(false); - break; - } - } else { - m_editConfig->m_cursorLineBg = QColor(g_config->getEditorCurrentLineBg()); - } - - m_editor->highlightCurrentLine(); -} - -void VEditOperations::handleEditConfigUpdated() -{ - // Reset to Normal mode. - if (m_vim) { - m_vim->setMode(VimMode::Normal); - } - - updateCursorLineBg(); -} - -void VEditOperations::handleVimModeChanged(VimMode p_mode) -{ - // Only highlight current visual line in Insert mode. - m_editConfig->m_highlightWholeBlock = (p_mode != VimMode::Insert); - - updateCursorLineBg(); -} - -void VEditOperations::requestUpdateVimStatus() -{ - emit vimStatusUpdated(m_vim); -} - -void VEditOperations::setVimMode(VimMode p_mode) -{ - if (m_vim && m_editConfig->m_enableVimMode) { - m_vim->setMode(p_mode); - } -} diff --git a/src/veditoperations.h b/src/veditoperations.h deleted file mode 100644 index 32f92e9e..00000000 --- a/src/veditoperations.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef VEDITOPERATIONS_H -#define VEDITOPERATIONS_H - -#include -#include -#include -#include -#include "vfile.h" -#include "utils/vvim.h" - -class VEditor; -class VEditConfig; -class QMimeData; -class QKeyEvent; - -class VEditOperations: public QObject -{ - Q_OBJECT -public: - VEditOperations(VEditor *p_editor, VFile *p_file); - - virtual ~VEditOperations(); - - virtual bool insertImageFromMimeData(const QMimeData *source) = 0; - - virtual bool insertImage() = 0; - - virtual bool insertImageFromURL(const QUrl &p_imageUrl) = 0; - - virtual bool insertLink(const QString &p_linkText, - const QString &p_linkUrl) = 0; - - // Return true if @p_event has been handled and no need to be further - // processed. - virtual bool handleKeyPressEvent(QKeyEvent *p_event) = 0; - - // Request to propogate Vim status. - void requestUpdateVimStatus(); - - // Insert decoration markers or decorate selected text. - virtual void decorateText(TextDecoration p_decoration, int p_level = -1) - { - Q_UNUSED(p_decoration); - Q_UNUSED(p_level); - } - - // Set Vim mode if not NULL. - void setVimMode(VimMode p_mode); - -signals: - // Want to display a template message in status bar. - void statusMessage(const QString &p_msg); - - // Propogate Vim status. - void vimStatusUpdated(const VVim *p_vim); - -protected slots: - // Handle the update of VEditConfig of the editor. - virtual void handleEditConfigUpdated(); - - // Vim mode changed. - void handleVimModeChanged(VimMode p_mode); - -private: - // Update m_editConfig->m_cursorLineBg. - void updateCursorLineBg(); - -protected: - void insertTextAtCurPos(const QString &p_text); - - VEditor *m_editor; - QPointer m_file; - VEditConfig *m_editConfig; - VVim *m_vim; -}; - -#endif // VEDITOPERATIONS_H diff --git a/src/veditor.cpp b/src/veditor.cpp deleted file mode 100644 index b5dca387..00000000 --- a/src/veditor.cpp +++ /dev/null @@ -1,919 +0,0 @@ -#include "veditor.h" - -#include -#include - -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "utils/veditutils.h" -#include "veditoperations.h" -#include "dialog/vinsertlinkdialog.h" -#include "utils/vmetawordmanager.h" -#include "utils/vvim.h" - -extern VConfigManager *g_config; - -extern VMetaWordManager *g_mwMgr; - -VEditor::VEditor(VFile *p_file, QWidget *p_editor) - : m_editor(p_editor), - m_object(new VEditorObject(this, p_editor)), - m_file(p_file), - m_editOps(nullptr), - m_document(nullptr), - m_enableInputMethod(true) -{ -} - -VEditor::~VEditor() -{ -} - -void VEditor::init() -{ - const int labelTimerInterval = 500; - const int extraSelectionHighlightTimer = 500; - const int labelSize = 64; - - m_document = documentW(); - - m_selectedWordColor = QColor(g_config->getEditorSelectedWordBg()); - m_searchedWordColor = QColor(g_config->getEditorSearchedWordBg()); - m_searchedWordCursorColor = QColor(g_config->getEditorSearchedWordCursorBg()); - m_incrementalSearchedWordColor = QColor(g_config->getEditorIncrementalSearchedWordBg()); - m_trailingSpaceColor = QColor(g_config->getEditorTrailingSpaceBg()); - - QPixmap wrapPixmap(":/resources/icons/search_wrap.svg"); - m_wrapLabel = new QLabel(m_editor); - m_wrapLabel->setPixmap(wrapPixmap.scaled(labelSize, labelSize)); - m_wrapLabel->hide(); - m_labelTimer = new QTimer(m_editor); - m_labelTimer->setSingleShot(true); - m_labelTimer->setInterval(labelTimerInterval); - QObject::connect(m_labelTimer, &QTimer::timeout, - m_object, &VEditorObject::labelTimerTimeout); - - m_highlightTimer = new QTimer(m_editor); - m_highlightTimer->setSingleShot(true); - m_highlightTimer->setInterval(extraSelectionHighlightTimer); - QObject::connect(m_highlightTimer, &QTimer::timeout, - m_object, &VEditorObject::doHighlightExtraSelections); - - m_extraSelections.resize((int)SelectionId::MaxSelection); - - updateFontAndPalette(); - - m_config.init(QFontMetrics(m_editor->font()), false); - updateEditConfig(); -} - -void VEditor::labelTimerTimeout() -{ - m_wrapLabel->hide(); -} - -void VEditor::doHighlightExtraSelections() -{ - int nrExtra = m_extraSelections.size(); - Q_ASSERT(nrExtra == (int)SelectionId::MaxSelection); - QList extraSelects; - for (int i = 0; i < nrExtra; ++i) { - extraSelects.append(m_extraSelections[i]); - } - - setExtraSelectionsW(extraSelects); -} - -void VEditor::updateEditConfig() -{ - m_config.update(QFontMetrics(m_editor->font())); - - if (m_config.m_tabStopWidth > 0) { - setTabStopWidthW(m_config.m_tabStopWidth); - } - - emit m_object->configUpdated(); -} - -void VEditor::highlightOnCursorPositionChanged() -{ - static QTextCursor lastCursor; - - QTextCursor cursor = textCursorW(); - if (lastCursor.isNull() || cursor.blockNumber() != lastCursor.blockNumber()) { - highlightCurrentLine(); - highlightTrailingSpace(); - } else { - // Judge whether we have trailing space at current line. - QString text = cursor.block().text(); - if (text.rbegin()->isSpace()) { - highlightTrailingSpace(); - } - - // Handle word-wrap in one block. - // Highlight current line if in different visual line. - if ((lastCursor.positionInBlock() - lastCursor.columnNumber()) != - (cursor.positionInBlock() - cursor.columnNumber())) { - highlightCurrentLine(); - } - } - - lastCursor = cursor; -} - -void VEditor::highlightCurrentLine() -{ - QList &selects = m_extraSelections[(int)SelectionId::CurrentLine]; - if (g_config->getHighlightCursorLine()) { - // Need to highlight current line. - selects.clear(); - - // A long block maybe splited into multiple visual lines. - QTextEdit::ExtraSelection select; - select.format.setBackground(m_config.m_cursorLineBg); - select.format.setProperty(QTextFormat::FullWidthSelection, true); - - QTextCursor cursor = textCursorW(); - if (m_config.m_highlightWholeBlock) { - cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor, 1); - QTextBlock block = cursor.block(); - int blockEnd = block.position() + block.length(); - int pos = -1; - while (cursor.position() < blockEnd && pos != cursor.position()) { - QTextEdit::ExtraSelection newSelect = select; - newSelect.cursor = cursor; - selects.append(newSelect); - - pos = cursor.position(); - cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, 1); - } - } else { - cursor.clearSelection(); - select.cursor = cursor; - selects.append(select); - } - } else { - // Need to clear current line highlight. - if (selects.isEmpty()) { - return; - } - - selects.clear(); - } - - highlightExtraSelections(true); -} - -// Do not highlight trailing spaces with current cursor right behind. -static void trailingSpaceFilter(VEditor *p_editor, QList &p_result) -{ - QTextCursor cursor = p_editor->textCursorW(); - if (!cursor.atBlockEnd()) { - return; - } - - int cursorPos = cursor.position(); - for (auto it = p_result.begin(); it != p_result.end(); ++it) { - if (it->cursor.selectionEnd() == cursorPos) { - p_result.erase(it); - - // There will be only one. - return; - } - } -} - -void VEditor::highlightTrailingSpace() -{ - if (!g_config->getEnableTrailingSpaceHighlight()) { - QList &selects = m_extraSelections[(int)SelectionId::TrailingSapce]; - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - return; - } - - QTextCharFormat format; - format.setBackground(m_trailingSpaceColor); - QString text("\\s+$"); - highlightTextAll(text, - FindOption::RegularExpression, - SelectionId::TrailingSapce, - format, - trailingSpaceFilter); -} - -void VEditor::highlightExtraSelections(bool p_now) -{ - m_highlightTimer->stop(); - if (p_now) { - doHighlightExtraSelections(); - } else { - m_highlightTimer->start(); - } -} - -void VEditor::highlightTextAll(const QString &p_text, - uint p_options, - SelectionId p_id, - QTextCharFormat p_format, - void (*p_filter)(VEditor *, - QList &)) -{ - QList &selects = m_extraSelections[(int)p_id]; - if (!p_text.isEmpty()) { - selects.clear(); - - QList occurs = findTextAll(p_text, p_options); - for (int i = 0; i < occurs.size(); ++i) { - QTextEdit::ExtraSelection select; - select.format = p_format; - select.cursor = occurs[i]; - selects.append(select); - } - } else { - if (selects.isEmpty()) { - return; - } - selects.clear(); - } - - if (p_filter) { - p_filter(this, selects); - } - - highlightExtraSelections(); -} - -QList VEditor::findTextAll(const QString &p_text, uint p_options) -{ - QList results; - if (p_text.isEmpty()) { - return results; - } - - // Options - QTextDocument::FindFlags findFlags; - bool caseSensitive = false; - if (p_options & FindOption::CaseSensitive) { - findFlags |= QTextDocument::FindCaseSensitively; - caseSensitive = true; - } - - if (p_options & FindOption::WholeWordOnly) { - findFlags |= QTextDocument::FindWholeWords; - } - - // Use regular expression - bool useRegExp = false; - QRegExp exp; - if (p_options & FindOption::RegularExpression) { - useRegExp = true; - exp = QRegExp(p_text, - caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); - } - - int startPos = 0; - QTextCursor cursor; - while (true) { - if (useRegExp) { - cursor = m_document->find(exp, startPos, findFlags); - } else { - cursor = m_document->find(p_text, startPos, findFlags); - } - - if (cursor.isNull()) { - break; - } else { - results.append(cursor); - startPos = cursor.selectionEnd(); - } - } - - return results; -} - -void VEditor::highlightSelectedWord() -{ - QList &selects = m_extraSelections[(int)SelectionId::SelectedWord]; - if (!g_config->getHighlightSelectedWord()) { - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - - return; - } - - QString text = textCursorW().selectedText().trimmed(); - if (text.isEmpty() || wordInSearchedSelection(text)) { - selects.clear(); - highlightExtraSelections(true); - return; - } - - QTextCharFormat format; - format.setBackground(m_selectedWordColor); - highlightTextAll(text, - FindOption::CaseSensitive, - SelectionId::SelectedWord, - format); -} - -bool VEditor::wordInSearchedSelection(const QString &p_text) -{ - QString text = p_text.trimmed(); - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeyword]; - for (int i = 0; i < selects.size(); ++i) { - QString searchedWord = selects[i].cursor.selectedText(); - if (text == searchedWord.trimmed()) { - return true; - } - } - - return false; -} - -bool VEditor::isModified() const -{ - return m_document->isModified(); -} - -void VEditor::setModified(bool p_modified) -{ - m_document->setModified(p_modified); -} - -void VEditor::insertImage() -{ - if (m_editOps) { - m_editOps->insertImage(); - } -} - -void VEditor::insertLink() -{ - if (!m_editOps) { - return; - } - - QString text; - QString linkText, linkUrl; - QTextCursor cursor = textCursorW(); - if (cursor.hasSelection()) { - text = VEditUtils::selectedText(cursor).trimmed(); - // Only pure space is accepted. - QRegExp reg("[\\S ]*"); - if (reg.exactMatch(text)) { - QUrl url = QUrl::fromUserInput(text, - m_file->fetchBasePath()); - QRegExp urlReg("[\\.\\\\/]"); - if (url.isValid() - && text.contains(urlReg)) { - // Url. - linkUrl = text; - } else { - // Text. - linkText = text; - } - } - } - - VInsertLinkDialog dialog(QObject::tr("Insert Link"), - "", - "", - linkText, - linkUrl, - m_editor); - if (dialog.exec() == QDialog::Accepted) { - linkText = dialog.getLinkText(); - linkUrl = dialog.getLinkUrl(); - Q_ASSERT(!linkText.isEmpty() && !linkUrl.isEmpty()); - - m_editOps->insertLink(linkText, linkUrl); - } -} - -bool VEditor::peekText(const QString &p_text, uint p_options, bool p_forward) -{ - if (p_text.isEmpty()) { - makeBlockVisible(m_document->findBlock(textCursorW().selectionStart())); - highlightIncrementalSearchedWord(QTextCursor()); - return false; - } - - bool wrapped = false; - QTextCursor retCursor; - bool found = findTextHelper(p_text, - p_options, - p_forward, - p_forward ? textCursorW().position() + 1 - : textCursorW().position(), - wrapped, - retCursor); - if (found) { - makeBlockVisible(m_document->findBlock(retCursor.selectionStart())); - highlightIncrementalSearchedWord(retCursor); - } - - return found; -} - -bool VEditor::findText(const QString &p_text, - uint p_options, - bool p_forward, - QTextCursor *p_cursor, - QTextCursor::MoveMode p_moveMode, - bool p_useLeftSideOfCursor) -{ - clearIncrementalSearchedWordHighlight(); - - if (p_text.isEmpty()) { - clearSearchedWordHighlight(); - return false; - } - - QTextCursor cursor = textCursorW(); - bool wrapped = false; - QTextCursor retCursor; - int matches = 0; - int start = p_forward ? cursor.position() + 1 : cursor.position(); - if (p_cursor) { - start = p_forward ? p_cursor->position() + 1 : p_cursor->position(); - } - - if (p_useLeftSideOfCursor) { - --start; - } - - bool found = findTextHelper(p_text, p_options, p_forward, start, - wrapped, retCursor); - if (found) { - Q_ASSERT(!retCursor.isNull()); - if (wrapped) { - showWrapLabel(); - } - - if (p_cursor) { - p_cursor->setPosition(retCursor.selectionStart(), p_moveMode); - } else { - cursor.setPosition(retCursor.selectionStart(), p_moveMode); - setTextCursorW(cursor); - } - - highlightSearchedWord(p_text, p_options); - highlightSearchedWordUnderCursor(retCursor); - matches = m_extraSelections[(int)SelectionId::SearchedKeyword].size(); - } else { - clearSearchedWordHighlight(); - } - - if (matches == 0) { - emit m_object->statusMessage(QObject::tr("Found no match")); - } else { - emit m_object->statusMessage(QObject::tr("Found %1 %2").arg(matches) - .arg(matches > 1 ? QObject::tr("matches") - : QObject::tr("match"))); - } - - return found; -} - -void VEditor::highlightIncrementalSearchedWord(const QTextCursor &p_cursor) -{ - QList &selects = m_extraSelections[(int)SelectionId::IncrementalSearchedKeyword]; - if (!g_config->getHighlightSearchedWord() || !p_cursor.hasSelection()) { - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - - return; - } - - selects.clear(); - QTextEdit::ExtraSelection select; - select.format.setBackground(m_incrementalSearchedWordColor); - select.cursor = p_cursor; - selects.append(select); - - highlightExtraSelections(true); -} - -// Use QPlainTextEdit::find() instead of QTextDocument::find() because the later has -// bugs in searching backward. -bool VEditor::findTextHelper(const QString &p_text, - uint p_options, - bool p_forward, - int p_start, - bool &p_wrapped, - QTextCursor &p_cursor) -{ - p_wrapped = false; - bool found = false; - - // Options - QTextDocument::FindFlags findFlags; - bool caseSensitive = false; - if (p_options & FindOption::CaseSensitive) { - findFlags |= QTextDocument::FindCaseSensitively; - caseSensitive = true; - } - - if (p_options & FindOption::WholeWordOnly) { - findFlags |= QTextDocument::FindWholeWords; - } - - if (!p_forward) { - findFlags |= QTextDocument::FindBackward; - } - - // Use regular expression - bool useRegExp = false; - QRegExp exp; - if (p_options & FindOption::RegularExpression) { - useRegExp = true; - exp = QRegExp(p_text, - caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); - } - - // Store current state of the cursor. - QTextCursor cursor = textCursorW(); - if (cursor.position() != p_start) { - if (p_start < 0) { - p_start = 0; - } else if (p_start > m_document->characterCount()) { - p_start = m_document->characterCount(); - } - } - - QTextCursor startCursor = cursor; - // Will clear the selection. - startCursor.setPosition(p_start); - setTextCursorW(startCursor); - - while (!found) { - if (useRegExp) { - found = findW(exp, findFlags); - } else { - found = findW(p_text, findFlags); - } - - if (p_wrapped) { - break; - } - - if (!found) { - // Wrap to the other end of the document to search again. - p_wrapped = true; - QTextCursor wrapCursor = textCursorW(); - if (p_forward) { - wrapCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); - } else { - wrapCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); - } - - setTextCursorW(wrapCursor); - } - } - - if (found) { - p_cursor = textCursorW(); - } - - // Restore the original cursor. - setTextCursorW(cursor); - - return found; -} - -void VEditor::clearIncrementalSearchedWordHighlight(bool p_now) -{ - QList &selects = m_extraSelections[(int)SelectionId::IncrementalSearchedKeyword]; - if (selects.isEmpty()) { - return; - } - - selects.clear(); - highlightExtraSelections(p_now); -} - -void VEditor::clearSearchedWordHighlight() -{ - clearIncrementalSearchedWordHighlight(false); - clearSearchedWordUnderCursorHighlight(false); - - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeyword]; - if (selects.isEmpty()) { - return; - } - - selects.clear(); - highlightExtraSelections(true); -} - -void VEditor::clearSearchedWordUnderCursorHighlight(bool p_now) -{ - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeywordUnderCursor]; - if (selects.isEmpty()) { - return; - } - - selects.clear(); - highlightExtraSelections(p_now); -} - -void VEditor::showWrapLabel() -{ - int labelW = m_wrapLabel->width(); - int labelH = m_wrapLabel->height(); - int x = (m_editor->width() - labelW) / 2; - int y = (m_editor->height() - labelH) / 2; - if (x < 0) { - x = 0; - } - - if (y < 0) { - y = 0; - } - - m_wrapLabel->move(x, y); - m_wrapLabel->show(); - m_labelTimer->stop(); - m_labelTimer->start(); -} - -void VEditor::highlightSearchedWord(const QString &p_text, uint p_options) -{ - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeyword]; - if (!g_config->getHighlightSearchedWord() || p_text.isEmpty()) { - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - - return; - } - - QTextCharFormat format; - format.setBackground(m_searchedWordColor); - highlightTextAll(p_text, p_options, SelectionId::SearchedKeyword, format); -} - -void VEditor::highlightSearchedWordUnderCursor(const QTextCursor &p_cursor) -{ - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeywordUnderCursor]; - if (!p_cursor.hasSelection()) { - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - - return; - } - - selects.clear(); - QTextEdit::ExtraSelection select; - select.format.setBackground(m_searchedWordCursorColor); - select.cursor = p_cursor; - selects.append(select); - - highlightExtraSelections(true); -} - -void VEditor::replaceText(const QString &p_text, - uint p_options, - const QString &p_replaceText, - bool p_findNext) -{ - QTextCursor cursor = textCursorW(); - bool wrapped = false; - QTextCursor retCursor; - bool found = findTextHelper(p_text, - p_options, true, - cursor.position(), - wrapped, - retCursor); - if (found) { - if (retCursor.selectionStart() == cursor.position()) { - // Matched. - retCursor.beginEditBlock(); - retCursor.insertText(p_replaceText); - retCursor.endEditBlock(); - setTextCursorW(retCursor); - } - - if (p_findNext) { - findText(p_text, p_options, true); - } - } -} - -void VEditor::replaceTextAll(const QString &p_text, - uint p_options, - const QString &p_replaceText) -{ - // Replace from the start to the end and restore the cursor. - QTextCursor cursor = textCursorW(); - int nrReplaces = 0; - QTextCursor tmpCursor = cursor; - tmpCursor.setPosition(0); - setTextCursorW(tmpCursor); - int start = tmpCursor.position(); - while (true) { - bool wrapped = false; - QTextCursor retCursor; - bool found = findTextHelper(p_text, - p_options, - true, - start, - wrapped, - retCursor); - if (!found) { - break; - } else { - if (wrapped) { - // Wrap back. - break; - } - - nrReplaces++; - retCursor.beginEditBlock(); - retCursor.insertText(p_replaceText); - retCursor.endEditBlock(); - setTextCursorW(retCursor); - start = retCursor.position(); - } - } - - // Restore cursor position. - cursor.clearSelection(); - setTextCursorW(cursor); - qDebug() << "replace all" << nrReplaces << "occurences"; - - emit m_object->statusMessage(QObject::tr("Replace %1 %2").arg(nrReplaces) - .arg(nrReplaces > 1 ? QObject::tr("occurences") - : QObject::tr("occurence"))); -} - -void VEditor::evaluateMagicWords() -{ - QString text; - QTextCursor cursor = textCursorW(); - if (!cursor.hasSelection()) { - // Get the WORD in current cursor. - int start, end; - VEditUtils::findCurrentWORD(cursor, start, end); - - if (start == end) { - return; - } else { - cursor.setPosition(start); - cursor.setPosition(end, QTextCursor::KeepAnchor); - } - } - - text = VEditUtils::selectedText(cursor); - Q_ASSERT(!text.isEmpty()); - QString evaText = g_mwMgr->evaluate(text); - if (text != evaText) { - qDebug() << "evaluateMagicWords" << text << evaText; - - cursor.insertText(evaText); - - if (m_editOps) { - m_editOps->setVimMode(VimMode::Insert); - } - - setTextCursorW(cursor); - } -} - -void VEditor::setReadOnlyAndHighlightCurrentLine(bool p_readonly) -{ - setReadOnlyW(p_readonly); - highlightCurrentLine(); -} - -bool VEditor::handleMousePressEvent(QMouseEvent *p_event) -{ - if (p_event->button() == Qt::LeftButton - && p_event->modifiers() == Qt::ControlModifier - && !textCursorW().hasSelection()) { - m_oriMouseX = p_event->x(); - m_oriMouseY = p_event->y(); - m_readyToScroll = true; - m_mouseMoveScrolled = false; - p_event->accept(); - return true; - } - - m_readyToScroll = false; - m_mouseMoveScrolled = false; - - return false; -} - -bool VEditor::handleMouseReleaseEvent(QMouseEvent *p_event) -{ - if (m_mouseMoveScrolled || m_readyToScroll) { - viewportW()->setCursor(Qt::IBeamCursor); - m_readyToScroll = false; - m_mouseMoveScrolled = false; - p_event->accept(); - return true; - } - - m_readyToScroll = false; - m_mouseMoveScrolled = false; - - return false; -} - -bool VEditor::handleMouseMoveEvent(QMouseEvent *p_event) -{ - const int threshold = 5; - - if (m_readyToScroll) { - int deltaX = p_event->x() - m_oriMouseX; - int deltaY = p_event->y() - m_oriMouseY; - - if (qAbs(deltaX) >= threshold || qAbs(deltaY) >= threshold) { - m_oriMouseX = p_event->x(); - m_oriMouseY = p_event->y(); - - if (!m_mouseMoveScrolled) { - m_mouseMoveScrolled = true; - viewportW()->setCursor(Qt::SizeAllCursor); - } - - QScrollBar *verBar = verticalScrollBarW(); - QScrollBar *horBar = horizontalScrollBarW(); - if (verBar->isVisible()) { - verBar->setValue(verBar->value() - deltaY); - } - - if (horBar->isVisible()) { - horBar->setValue(horBar->value() - deltaX); - } - } - - p_event->accept(); - return true; - } - - return false; -} - -void VEditor::requestUpdateVimStatus() -{ - if (m_editOps) { - m_editOps->requestUpdateVimStatus(); - } else { - emit m_object->vimStatusUpdated(NULL); - } -} - -bool VEditor::handleInputMethodQuery(Qt::InputMethodQuery p_query, - QVariant &p_var) const -{ - if (p_query == Qt::ImEnabled) { - p_var = m_enableInputMethod; - return true; - } - - return false; -} - -void VEditor::setInputMethodEnabled(bool p_enabled) -{ - if (m_enableInputMethod != p_enabled) { - m_enableInputMethod = p_enabled; - - QInputMethod *im = QGuiApplication::inputMethod(); - im->reset(); - - // Ask input method to query current state, which will call inputMethodQuery(). - im->update(Qt::ImEnabled); - } -} - -void VEditor::decorateText(TextDecoration p_decoration, int p_level) -{ - if (m_editOps) { - m_editOps->decorateText(p_decoration, p_level); - } -} - -void VEditor::updateConfig() -{ - updateEditConfig(); -} - -void VEditor::setVimMode(VimMode p_mode) -{ - if (m_editOps) { - m_editOps->setVimMode(p_mode); - } -} diff --git a/src/veditor.h b/src/veditor.h deleted file mode 100644 index 2e631589..00000000 --- a/src/veditor.h +++ /dev/null @@ -1,389 +0,0 @@ -#ifndef VEDITOR_H -#define VEDITOR_H - -#include -#include -#include -#include -#include - -#include "veditconfig.h" -#include "vconstants.h" -#include "vfile.h" - -class QWidget; -class VEditorObject; -class VEditOperations; -class QTimer; -class QLabel; -class VVim; -enum class VimMode; -class QMouseEvent; - - -enum class SelectionId { - CurrentLine = 0, - SelectedWord, - SearchedKeyword, - SearchedKeywordUnderCursor, - IncrementalSearchedKeyword, - TrailingSapce, - MaxSelection -}; - - -// Abstract class for an edit. -// Should inherit this class as well as QPlainTextEdit or QTextEdit. -// Will replace VEdit eventually. -class VEditor -{ -public: - explicit VEditor(VFile *p_file, QWidget *p_editor); - - virtual ~VEditor(); - - void highlightCurrentLine(); - - virtual void beginEdit() = 0; - - virtual void endEdit() = 0; - - // Save buffer content to VFile. - virtual void saveFile() = 0; - - virtual void reloadFile() = 0; - - virtual bool scrollToBlock(int p_blockNumber) = 0; - - bool isModified() const; - - void setModified(bool p_modified); - - // User requests to insert an image. - void insertImage(); - - // User requests to insert a link. - void insertLink(); - - // Used for incremental search. - // User has enter the content to search, but does not enter the "find" button yet. - bool peekText(const QString &p_text, uint p_options, bool p_forward = true); - - // If @p_cursor is not null, set the position of @p_cursor instead of current - // cursor. - bool findText(const QString &p_text, - uint p_options, - bool p_forward, - QTextCursor *p_cursor = nullptr, - QTextCursor::MoveMode p_moveMode = QTextCursor::MoveAnchor, - bool p_useLeftSideOfCursor = false); - - void replaceText(const QString &p_text, - uint p_options, - const QString &p_replaceText, - bool p_findNext); - - void replaceTextAll(const QString &p_text, - uint p_options, - const QString &p_replaceText); - - // Scroll the content to make @p_block visible. - // If the @p_block is too long to hold in one page, just let it occupy the - // whole page. - // Will not change current cursor. - virtual void makeBlockVisible(const QTextBlock &p_block) = 0; - - // Clear IncrementalSearchedKeyword highlight. - void clearIncrementalSearchedWordHighlight(bool p_now = true); - - // Clear SearchedKeyword highlight. - void clearSearchedWordHighlight(); - - // Clear SearchedKeywordUnderCursor Highlight. - void clearSearchedWordUnderCursorHighlight(bool p_now = true); - - // Evaluate selected text or cursor word as magic words. - void evaluateMagicWords(); - - VFile *getFile() const; - - VEditConfig &getConfig(); - - // Request to update Vim status. - void requestUpdateVimStatus(); - - // Jump to a title. - // @p_forward: jump forward or backward. - // @p_relativeLevel: 0 for the same level as current header; - // negative value for upper level; - // positive value is ignored. - // Returns true if the jump succeeded. - virtual bool jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat) = 0; - - void setInputMethodEnabled(bool p_enabled); - - // Insert decoration markers or decorate selected text. - void decorateText(TextDecoration p_decoration, int p_level); - - virtual bool isBlockVisible(const QTextBlock &p_block) = 0; - - VEditorObject *object() const; - - QWidget *getEditor() const; - - // Scroll block @p_blockNum into the visual window. - // @p_dest is the position of the window: 0 for top, 1 for center, 2 for bottom. - // @p_blockNum is based on 0. - // Will set the cursor to the block. - virtual void scrollBlockInPage(int p_blockNum, int p_dest) = 0; - - // Update config according to global configurations. - virtual void updateConfig(); - - void setVimMode(VimMode p_mode); - - virtual QString getContent() const = 0; - - // @p_modified: if true, delete the whole content and insert the new content. - virtual void setContent(const QString &p_content, bool p_modified = false) = 0; - -// Wrapper functions for QPlainTextEdit/QTextEdit. -// Ends with W to distinguish it from the original interfaces. -public: - virtual void setExtraSelectionsW(const QList &p_selections) = 0; - - virtual QTextDocument *documentW() const = 0; - - virtual void setTabStopWidthW(int p_width) = 0; - - virtual QTextCursor textCursorW() const = 0; - - virtual void setTextCursorW(const QTextCursor &p_cursor) = 0; - - virtual void moveCursorW(QTextCursor::MoveOperation p_operation, - QTextCursor::MoveMode p_mode = QTextCursor::MoveAnchor) = 0; - - virtual QScrollBar *verticalScrollBarW() const = 0; - - virtual QScrollBar *horizontalScrollBarW() const = 0; - - virtual bool findW(const QString &p_exp, - QTextDocument::FindFlags p_options = QTextDocument::FindFlags()) = 0; - - virtual bool findW(const QRegExp &p_exp, - QTextDocument::FindFlags p_options = QTextDocument::FindFlags()) = 0; - - virtual void setReadOnlyW(bool p_ro) = 0; - - virtual QWidget *viewportW() const = 0; - - virtual void insertPlainTextW(const QString &p_text) = 0; - - virtual void undoW() = 0; - - virtual void redoW() = 0; - - // Whether display cursor as block. - virtual void setCursorBlockModeW(CursorBlock p_mode) = 0; - -protected: - void init(); - - virtual void updateFontAndPalette() = 0; - - // Update m_config according to VConfigManager. - void updateEditConfig(); - - // Do some highlight on cursor position changed. - void highlightOnCursorPositionChanged(); - - // Highlight selected text. - void highlightSelectedWord(); - - bool wordInSearchedSelection(const QString &p_text); - - // Set read-only property and highlight current line. - void setReadOnlyAndHighlightCurrentLine(bool p_readonly); - - // Handle the mouse press event of m_editor. - // Returns true if no further process is needed. - bool handleMousePressEvent(QMouseEvent *p_event); - - bool handleMouseReleaseEvent(QMouseEvent *p_event); - - bool handleMouseMoveEvent(QMouseEvent *p_event); - - bool handleInputMethodQuery(Qt::InputMethodQuery p_query, - QVariant &p_var) const; - - QWidget *m_editor; - - VEditorObject *m_object; - - QPointer m_file; - - VEditOperations *m_editOps; - - VEditConfig m_config; - -private: - friend class VEditorObject; - - void highlightTrailingSpace(); - - // Trigger the timer to request highlight. - // If @p_now is true, stop the timer and highlight immediately. - void highlightExtraSelections(bool p_now = false); - - // @p_fileter: a function to filter out highlight results. - void highlightTextAll(const QString &p_text, - uint p_options, - SelectionId p_id, - QTextCharFormat p_format, - void (*p_filter)(VEditor *, - QList &) = NULL); - - // Find all the occurences of @p_text. - QList findTextAll(const QString &p_text, uint p_options); - - // Highlight @p_cursor as the incremental searched keyword. - void highlightIncrementalSearchedWord(const QTextCursor &p_cursor); - - // Find @p_text in the document starting from @p_start. - // Returns true if @p_text is found and set @p_cursor to indicate - // the position. - // Will NOT change current cursor. - bool findTextHelper(const QString &p_text, - uint p_options, - bool p_forward, - int p_start, - bool &p_wrapped, - QTextCursor &p_cursor); - - void showWrapLabel(); - - void highlightSearchedWord(const QString &p_text, uint p_options); - - // Highlight @p_cursor as the searched keyword under cursor. - void highlightSearchedWordUnderCursor(const QTextCursor &p_cursor); - - QLabel *m_wrapLabel; - QTimer *m_labelTimer; - - QTextDocument *m_document; - - // doHighlightExtraSelections() will highlight these selections. - // Selections are indexed by SelectionId. - QVector > m_extraSelections; - - QColor m_selectedWordColor; - QColor m_searchedWordColor; - QColor m_searchedWordCursorColor; - QColor m_incrementalSearchedWordColor; - QColor m_trailingSpaceColor; - - // Timer for extra selections highlight. - QTimer *m_highlightTimer; - - bool m_readyToScroll; - bool m_mouseMoveScrolled; - int m_oriMouseX; - int m_oriMouseY; - - // Whether enable input method. - bool m_enableInputMethod; - -// Functions for private slots. -private: - void labelTimerTimeout(); - - // Do the real work to highlight extra selections. - void doHighlightExtraSelections(); -}; - - -// Since one class could not inherit QObject multiple times, we use this class -// for VEditor to signal/slot. -class VEditorObject : public QObject -{ - Q_OBJECT -public: - explicit VEditorObject(VEditor *p_editor, QObject *p_parent = nullptr) - : QObject(p_parent), m_editor(p_editor) - { - } - -signals: - // Emit when editor config has been updated. - void configUpdated(); - - // Emit when want to show message in status bar. - void statusMessage(const QString &p_msg); - - // Request VEditTab to save and exit edit mode. - void saveAndRead(); - - // Request VEditTab to discard and exit edit mode. - void discardAndRead(); - - // Request VEditTab to edit current note. - void editNote(); - - // Request VEditTab to save this file. - void saveNote(); - - // Emit when Vim status updated. - void vimStatusUpdated(const VVim *p_vim); - - // Emit when all initialization is ready. - void ready(); - - // Request the edit tab to close find and replace dialog. - void requestCloseFindReplaceDialog(); - - void mouseMoved(QMouseEvent *p_event); - - void mousePressed(QMouseEvent *p_event); - - void mouseReleased(QMouseEvent *p_event); - -private slots: - // Timer for find-wrap label. - void labelTimerTimeout() - { - m_editor->labelTimerTimeout(); - } - - // Do the real work to highlight extra selections. - void doHighlightExtraSelections() - { - m_editor->doHighlightExtraSelections(); - } - -private: - friend class VEditor; - - VEditor *m_editor; -}; - -inline VFile *VEditor::getFile() const -{ - return m_file; -} - -inline VEditConfig &VEditor::getConfig() -{ - return m_config; -} - -inline VEditorObject *VEditor::object() const -{ - return m_object; -} - -inline QWidget *VEditor::getEditor() const -{ - return m_editor; -} - -#endif // VEDITOR_H diff --git a/src/vedittab.cpp b/src/vedittab.cpp deleted file mode 100644 index 0832b3ca..00000000 --- a/src/vedittab.cpp +++ /dev/null @@ -1,196 +0,0 @@ -#include "vedittab.h" -#include -#include - -#include "utils/vutils.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -VEditTab::VEditTab(VFile *p_file, VEditArea *p_editArea, QWidget *p_parent) - : QWidget(p_parent), - m_file(p_file), - m_isEditMode(false), - m_outline(p_file), - m_currentHeader(p_file, -1), - m_editArea(p_editArea), - m_checkFileChange(true), - m_fileDiverged(false), - m_ready(0), - m_enableBackupFile(g_config->getEnableBackupFile()) -{ - connect(qApp, &QApplication::focusChanged, - this, &VEditTab::handleFocusChanged); -} - -VEditTab::~VEditTab() -{ - if (m_file) { - m_file->close(); - } -} - -void VEditTab::focusTab() -{ - focusChild(); - emit getFocused(); - updateStatus(); -} - -bool VEditTab::isEditMode() const -{ - return m_isEditMode; -} - -bool VEditTab::isModified() const -{ - return false; -} - -VFile *VEditTab::getFile() const -{ - return m_file; -} - -void VEditTab::handleFocusChanged(QWidget * /* p_old */, QWidget *p_now) -{ - if (p_now == this) { - // When VEditTab get focus, it should focus to current widget. - focusChild(); - - emit getFocused(); - updateStatus(); - } else if (isAncestorOf(p_now)) { - emit getFocused(); - updateStatus(); - } -} - -void VEditTab::wheelEvent(QWheelEvent *p_event) -{ - QPoint angle = p_event->angleDelta(); - Qt::KeyboardModifiers modifiers = p_event->modifiers(); - if (!angle.isNull() && (angle.y() != 0) && (modifiers & Qt::ControlModifier)) { - // Zoom in/out current tab. - zoom(angle.y() > 0); - - p_event->accept(); - return; - } - - p_event->ignore(); -} - -VEditTabInfo VEditTab::fetchTabInfo(VEditTabInfo::InfoType p_type) const -{ - VEditTabInfo info; - info.m_type = p_type; - info.m_editTab = const_cast(this); - - return info; -} - -const VHeaderPointer &VEditTab::getCurrentHeader() const -{ - return m_currentHeader; -} - -const VTableOfContent &VEditTab::getOutline() const -{ - return m_outline; -} - -void VEditTab::tryRestoreFromTabInfo(const VEditTabInfo &p_info) -{ - if (p_info.m_editTab != this) { - m_infoToRestore.clear(); - return; - } - - if (restoreFromTabInfo(p_info)) { - m_infoToRestore.clear(); - return; - } - - // Save it and restore later. - m_infoToRestore = p_info; -} - -void VEditTab::updateStatus() -{ - emit statusUpdated(fetchTabInfo()); -} - -void VEditTab::evaluateMagicWords() -{ -} - -bool VEditTab::tabHasFocus() const -{ - QWidget *wid = QApplication::focusWidget(); - return wid == this || isAncestorOf(wid); -} - -void VEditTab::insertLink() -{ -} - -void VEditTab::applySnippet(const VSnippet *p_snippet) -{ - Q_UNUSED(p_snippet); -} - -void VEditTab::applySnippet() -{ -} - -void VEditTab::checkFileChangeOutside() -{ - if (!m_checkFileChange) { - return; - } - - if (m_file->isChangedOutside()) { - int ret = VUtils::showMessage(QMessageBox::Information, - tr("Information"), - tr("Note %2 has been modified by another program.") - .arg(g_config->c_dataTextStyle).arg(m_file->fetchPath()), - tr("Do you want to reload it?"), - QMessageBox::Yes | QMessageBox::No, - QMessageBox::Yes, - this); - switch (ret) { - case QMessageBox::Yes: - reloadFromDisk(); - break; - - case QMessageBox::No: - m_checkFileChange = false; - m_fileDiverged = true; - updateStatus(); - break; - - default: - Q_ASSERT(false); - break; - } - } -} - -void VEditTab::reloadFromDisk() -{ - m_file->reload(); - m_fileDiverged = false; - m_checkFileChange = true; - reload(); -} - -void VEditTab::writeBackupFile() -{ -} - -void VEditTab::handleFileOrDirectoryChange(bool p_isFile, UpdateAction p_act) -{ - Q_UNUSED(p_isFile); - Q_UNUSED(p_act); -} diff --git a/src/vedittab.h b/src/vedittab.h deleted file mode 100644 index a261d39c..00000000 --- a/src/vedittab.h +++ /dev/null @@ -1,188 +0,0 @@ -#ifndef VEDITTAB_H -#define VEDITTAB_H - -#include -#include -#include -#include "vtableofcontent.h" -#include "vfile.h" -#include "utils/vvim.h" -#include "vedittabinfo.h" - -class VEditArea; -class VSnippet; - -// VEditTab is the base class of an edit tab inside VEditWindow. -class VEditTab : public QWidget -{ - Q_OBJECT - -public: - VEditTab(VFile *p_file, VEditArea *p_editArea, QWidget *p_parent = 0); - - virtual ~VEditTab(); - - // Close current tab. - // @p_forced: if true, discard the changes. - virtual bool closeFile(bool p_forced) = 0; - - // Enter read mode. - virtual void readFile() = 0; - - // Save file. - virtual bool saveFile() = 0; - - bool isEditMode() const; - - virtual bool isModified() const; - - void focusTab(); - - // Whether this tab has focus. - bool tabHasFocus() const; - - // Scroll to @p_header. - // Will emit currentHeaderChanged() if @p_header is valid. - virtual void scrollToHeader(const VHeaderPointer &p_header) { Q_UNUSED(p_header) } - - VFile *getFile() const; - - // User requests to insert image. - virtual void insertImage() = 0; - - // User requests to insert link. - virtual void insertLink(); - - // Search @p_text in current note. - virtual void findText(const QString &p_text, uint p_options, bool p_peek, - bool p_forward = true) = 0; - - // Replace @p_text with @p_replaceText in current note. - virtual void replaceText(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext) = 0; - - virtual void replaceTextAll(const QString &p_text, uint p_options, - const QString &p_replaceText) = 0; - - // Return selected text. - virtual QString getSelectedText() const = 0; - - virtual void clearSearchedWordHighlight() = 0; - - // Request current tab to propogate its status about Vim. - virtual void requestUpdateVimStatus() = 0; - - // Insert decoration markers or decorate selected text. - virtual void decorateText(TextDecoration p_decoration, int p_level = -1) - { - Q_UNUSED(p_decoration); - Q_UNUSED(p_level); - } - - // Create a filled VEditTabInfo. - virtual VEditTabInfo fetchTabInfo(VEditTabInfo::InfoType p_type = VEditTabInfo::InfoType::All) const; - - const VTableOfContent &getOutline() const; - - const VHeaderPointer &getCurrentHeader() const; - - // Restore status from @p_info. - // If this tab is not ready yet, it will restore once it is ready. - void tryRestoreFromTabInfo(const VEditTabInfo &p_info); - - // Emit signal to update current status. - virtual void updateStatus(); - - // Called by evaluateMagicWordsByCaptain() to evaluate the magic words. - virtual void evaluateMagicWords(); - - // Insert snippet @p_snippet. - virtual void applySnippet(const VSnippet *p_snippet); - - // Prompt for user to apply a snippet. - virtual void applySnippet(); - - // Check whether this file has been changed outside. - void checkFileChangeOutside(); - - // Reload the editor from file. - virtual void reload() = 0; - - // Reload file from disk and reload the editor. - void reloadFromDisk(); - - // Handle the change of file or directory, such as the file has been moved. - virtual void handleFileOrDirectoryChange(bool p_isFile, UpdateAction p_act); - -public slots: - // Enter edit mode - virtual void editFile() = 0; - -protected: - void wheelEvent(QWheelEvent *p_event) Q_DECL_OVERRIDE; - - // Called when VEditTab get focus. Should focus the proper child widget. - virtual void focusChild() = 0; - - // Called to zoom in/out content. - virtual void zoom(bool p_zoomIn, qreal p_step = 0.25) = 0; - - // Restore from @p_fino. - // Return true if succeed. - virtual bool restoreFromTabInfo(const VEditTabInfo &p_info) = 0; - - // Write modified buffer content to backup file. - virtual void writeBackupFile(); - - // File related to this tab. - QPointer m_file; - - bool m_isEditMode; - - // Table of content of this tab. - VTableOfContent m_outline; - - // Current header in m_outline of this tab. - VHeaderPointer m_currentHeader; - - VEditArea *m_editArea; - - // Tab info to restore from once ready. - VEditTabInfo m_infoToRestore; - - // Whether check the file change outside. - bool m_checkFileChange; - - // File has diverged from disk. - bool m_fileDiverged; - - // Tab has been ready or not. - int m_ready; - - // Whether backup file is enabled. - bool m_enableBackupFile; - -signals: - void getFocused(); - - void outlineChanged(const VTableOfContent &p_outline); - - void currentHeaderChanged(const VHeaderPointer &p_header); - - // The status of current tab has updates. - void statusUpdated(const VEditTabInfo &p_info); - - // Emit when want to show message in status bar. - void statusMessage(const QString &p_msg); - - void vimStatusUpdated(const VVim *p_vim); - - // Request to close itself. - void closeRequested(VEditTab *p_tab); - -private slots: - // Called when app focus changed. - void handleFocusChanged(QWidget *p_old, QWidget *p_now); -}; - -#endif // VEDITTAB_H diff --git a/src/vedittabinfo.h b/src/vedittabinfo.h deleted file mode 100644 index 3f4245c8..00000000 --- a/src/vedittabinfo.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef VEDITTABINFO_H -#define VEDITTABINFO_H - -class VEditTab; - -struct VEditTabInfo -{ - enum InfoType - { - // Update all information. - All = 0, - - // Update only cursor information. - Cursor - }; - - VEditTabInfo() - : m_type(InfoType::All), - m_editTab(NULL), - m_cursorBlockNumber(-1), - m_cursorPositionInBlock(-1), - m_blockCount(-1), - m_headerIndex(-1) - { - } - - void clear() - { - m_type = InfoType::All; - m_editTab = NULL; - m_cursorBlockNumber = -1; - m_cursorPositionInBlock = -1; - m_blockCount = -1; - m_headerIndex = -1; - } - - InfoType m_type; - - VEditTab *m_editTab; - - // Cursor information. -1 for invalid info. - int m_cursorBlockNumber; - int m_cursorPositionInBlock; - int m_blockCount; - - // Header index in outline. - int m_headerIndex; -}; - -#endif // VEDITTABINFO_H diff --git a/src/veditwindow.cpp b/src/veditwindow.cpp deleted file mode 100644 index 08be256d..00000000 --- a/src/veditwindow.cpp +++ /dev/null @@ -1,1128 +0,0 @@ -#include -#include -#include "veditwindow.h" -#include "vedittab.h" -#include "utils/vutils.h" -#include "vorphanfile.h" -#include "vmainwindow.h" -#include "veditarea.h" -#include "vopenedlistmenu.h" -#include "vmdtab.h" -#include "vhtmltab.h" -#include "vfilelist.h" -#include "vconfigmanager.h" -#include "utils/viconutils.h" - -extern VConfigManager *g_config; -extern VMainWindow *g_mainWin; - -VEditWindow::VEditWindow(VEditArea *editArea, QWidget *parent) - : QTabWidget(parent), - m_editArea(editArea), - m_curTabWidget(NULL), - m_lastTabWidget(NULL) -{ - setAcceptDrops(true); - initTabActions(); - setupCornerWidget(); - - // Explicit speficy in macOS. - setUsesScrollButtons(true); - setElideMode(Qt::ElideRight); - setTabsClosable(true); - setMovable(true); - setContextMenuPolicy(Qt::CustomContextMenu); - - QTabBar *bar = tabBar(); - bar->setContextMenuPolicy(Qt::CustomContextMenu); - connect(bar, &QTabBar::customContextMenuRequested, - this, &VEditWindow::tabbarContextMenuRequested); - - connect(this, &VEditWindow::tabCloseRequested, - this, &VEditWindow::closeTab); - connect(this, &VEditWindow::tabBarClicked, - this, &VEditWindow::handleTabbarClicked); - - connect(this, &VEditWindow::tabBarDoubleClicked, - this, [this](int p_index) { - if (p_index != -1 && g_config->getDoubleClickCloseTab()) { - closeTab(p_index); - } - }); - - connect(this, &VEditWindow::currentChanged, - this, &VEditWindow::handleCurrentIndexChanged); - connect(this, &VEditWindow::customContextMenuRequested, - this, &VEditWindow::contextMenuRequested); -} - -void VEditWindow::initTabActions() -{ - m_locateAct = new QAction(VIconUtils::menuIcon(":/resources/icons/locate_note.svg"), - tr("Locate To Folder"), this); - m_locateAct->setToolTip(tr("Locate the folder of current note")); - connect(m_locateAct, &QAction::triggered, - this, &VEditWindow::handleLocateAct); - - m_moveLeftAct = new QAction(VIconUtils::menuIcon(":/resources/icons/move_tab_left.svg"), - tr("Move One Split Left"), this); - m_moveLeftAct->setToolTip(tr("Move current tab to the split on the left")); - connect(m_moveLeftAct, &QAction::triggered, - this, &VEditWindow::handleMoveLeftAct); - - m_moveRightAct = new QAction(VIconUtils::menuIcon(":/resources/icons/move_tab_right.svg"), - tr("Move One Split Right"), this); - m_moveRightAct->setToolTip(tr("Move current tab to the split on the right")); - connect(m_moveRightAct, &QAction::triggered, - this, &VEditWindow::handleMoveRightAct); - - m_closeTabAct = new QAction(VIconUtils::menuIcon(":/resources/icons/close.svg"), - tr("Close Tab"), this); - m_closeTabAct->setToolTip(tr("Close current note tab")); - connect(m_closeTabAct, &QAction::triggered, - this, [this](){ - int tab = this->m_closeTabAct->data().toInt(); - Q_ASSERT(tab != -1); - closeTab(tab); - }); - - m_closeOthersAct = new QAction(tr("Close Other Tabs"), this); - m_closeOthersAct->setToolTip(tr("Close all other note tabs")); - connect(m_closeOthersAct, &QAction::triggered, - this, [this](){ - int tab = this->m_closeTabAct->data().toInt(); - Q_ASSERT(tab != -1); - - for (int i = tab - 1; i >= 0; --i) { - this->setCurrentIndex(i); - this->updateTabStatus(i); - if (this->closeTab(i)) { - --tab; - } - } - - for (int i = tab + 1; i < this->count();) { - this->setCurrentIndex(i); - this->updateTabStatus(i); - if (!this->closeTab(i)) { - ++i; - } - } - }); - - m_closeRightAct = new QAction(tr("Close Tabs To The Right"), this); - m_closeRightAct->setToolTip(tr("Close all the note tabs to the right of current tab")); - connect(m_closeRightAct, &QAction::triggered, - this, [this](){ - int tab = this->m_closeTabAct->data().toInt(); - Q_ASSERT(tab != -1); - - for (int i = tab + 1; i < this->count();) { - this->setCurrentIndex(i); - this->updateTabStatus(i); - if (!this->closeTab(i)) { - ++i; - } - } - }); - - m_noteInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/note_info.svg"), - tr("Note Info"), this); - m_noteInfoAct->setToolTip(tr("View and edit information of the note")); - connect(m_noteInfoAct, &QAction::triggered, - this, [this](){ - int tab = this->m_closeTabAct->data().toInt(); - Q_ASSERT(tab != -1); - - VEditTab *editor = getTab(tab); - QPointer file = editor->getFile(); - Q_ASSERT(file); - if (file->getType() == FileType::Note) { - VNoteFile *tmpFile = dynamic_cast((VFile *)file); - g_mainWin->getFileList()->fileInfo(tmpFile); - } else if (file->getType() == FileType::Orphan) { - g_mainWin->editOrphanFileInfo(file); - } - }); - - m_openLocationAct = new QAction(tr("Open Note Location"), this); - m_openLocationAct->setToolTip(tr("Open the folder containing this note in operating system")); - connect(m_openLocationAct, &QAction::triggered, - this, [this](){ - int tab = this->m_closeTabAct->data().toInt(); - Q_ASSERT(tab != -1); - - VEditTab *editor = getTab(tab); - QPointer file = editor->getFile(); - Q_ASSERT(file); - QUrl url = QUrl::fromLocalFile(file->fetchBasePath()); - QDesktopServices::openUrl(url); - }); - - m_reloadAct = new QAction(tr("Reload From Disk"), this); - m_reloadAct->setToolTip(tr("Reload the content of this note from disk")); - connect(m_reloadAct, &QAction::triggered, - this, [this](){ - int tab = this->m_closeTabAct->data().toInt(); - Q_ASSERT(tab != -1); - - VEditTab *editor = getTab(tab); - editor->reloadFromDisk(); - }); - - m_recycleBinAct = new QAction(VIconUtils::menuIcon(":/resources/icons/recycle_bin.svg"), - tr("&Recycle Bin"), this); - m_recycleBinAct->setToolTip(tr("Open the recycle bin of this note")); - connect(m_recycleBinAct, &QAction::triggered, - this, [this]() { - int tab = this->m_closeTabAct->data().toInt(); - Q_ASSERT(tab != -1); - - VEditTab *editor = getTab(tab); - VFile *file = editor->getFile(); - Q_ASSERT(file); - - QString folderPath; - if (file->getType() == FileType::Note) { - const VNoteFile *tmpFile = dynamic_cast((VFile *)file); - folderPath = tmpFile->getNotebook()->getRecycleBinFolderPath(); - } else if (file->getType() == FileType::Orphan) { - const VOrphanFile *tmpFile = dynamic_cast((VFile *)file); - folderPath = tmpFile->fetchRecycleBinFolderPath(); - } else { - Q_ASSERT(false); - } - - QUrl url = QUrl::fromLocalFile(folderPath); - QDesktopServices::openUrl(url); - }); -} - -void VEditWindow::setupCornerWidget() -{ - // Left button - leftBtn = new QPushButton(VIconUtils::editWindowCornerIcon(":/resources/icons/corner_tablist.svg"), - "", this); - leftBtn->setProperty("CornerBtn", true); - leftBtn->setToolTip(tr("Opened Notes List")); - VOpenedListMenu *leftMenu = new VOpenedListMenu(this); - leftMenu->setToolTipsVisible(true); - connect(leftMenu, &VOpenedListMenu::fileTriggered, - this, &VEditWindow::tabListJump); - leftBtn->setMenu(leftMenu); - - // Right button - // Actions - splitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/split_window.svg"), - tr("Split"), this); - splitAct->setToolTip(tr("Split current window vertically")); - connect(splitAct, &QAction::triggered, - this, [this](){ - splitWindow(true); - }); - - removeSplitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/remove_split.svg"), - tr("Remove split"), this); - removeSplitAct->setToolTip(tr("Remove current split window")); - connect(removeSplitAct, &QAction::triggered, - this, &VEditWindow::removeSplit); - - rightBtn = new QPushButton(VIconUtils::editWindowCornerIcon(":/resources/icons/corner_menu.svg"), - "", this); - rightBtn->setProperty("CornerBtn", true); - rightBtn->setToolTip(tr("Menu")); - QMenu *rightMenu = new QMenu(this); - rightMenu->setToolTipsVisible(true); - rightMenu->addAction(splitAct); - rightMenu->addAction(removeSplitAct); - rightBtn->setMenu(rightMenu); - connect(rightMenu, &QMenu::aboutToShow, - this, &VEditWindow::updateSplitMenu); - - // Move all buttons to the right corner. - QWidget *widget = new QWidget(this); - QHBoxLayout *layout = new QHBoxLayout(); - layout->addWidget(leftBtn); - layout->addWidget(rightBtn); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - widget->setLayout(layout); - - setCornerWidget(widget, Qt::TopRightCorner); -} - -void VEditWindow::splitWindow(bool p_right) -{ - emit requestSplitWindow(this, p_right); -} - -void VEditWindow::removeSplit() -{ - // Close all the files one by one - // If user do not want to close a file, just stop removing. - // Otherwise, closeAllFiles() will emit requestRemoveSplit. - closeAllFiles(false); -} - -void VEditWindow::removeEditTab(int p_index) -{ - Q_ASSERT(p_index > -1 && p_index < tabBar()->count()); - - VEditTab *editor = getTab(p_index); - removeTab(p_index); - delete editor; -} - -int VEditWindow::insertEditTab(int p_index, VFile *p_file, QWidget *p_page) -{ - int idx = insertTab(p_index, - p_page, - p_file->getName()); - updateTabInfo(idx); - return idx; -} - -int VEditWindow::appendEditTab(VFile *p_file, QWidget *p_page) -{ - return insertEditTab(count(), p_file, p_page); -} - -int VEditWindow::openFile(VFile *p_file, OpenFileMode p_mode) -{ - qDebug() << "open" << p_file->getName(); - // Find if it has been opened already - int idx = findTabByFile(p_file); - if (idx > -1) { - goto out; - } - idx = openFileInTab(p_file, p_mode); - -out: - setCurrentIndex(idx); - focusWindow(); - return idx; -} - -// Return true if we closed the file actually -bool VEditWindow::closeFile(const VFile *p_file, bool p_forced) -{ - // Find if it has been opened already - int idx = findTabByFile(p_file); - if (idx == -1) { - return false; - } - - VEditTab *editor = getTab(idx); - Q_ASSERT(editor); - VEditTabInfo tabInfo = editor->fetchTabInfo(); - VFileSessionInfo info = VFileSessionInfo::fromEditTabInfo(&tabInfo); - if (!p_forced) { - setCurrentIndex(idx); - updateTabStatus(idx); - } - - // Even p_forced is true we need to delete unused images. - bool ok = editor->closeFile(p_forced); - if (ok) { - removeEditTab(idx); - - m_editArea->recordClosedFile(info); - } - - if (count() == 0) { - emit requestRemoveSplit(this); - } - - return ok; -} - -bool VEditWindow::closeFile(const VDirectory *p_dir, bool p_forced) -{ - Q_ASSERT(p_dir); - int i = 0; - while (i < count()) { - VEditTab *editor = getTab(i); - QPointer file = editor->getFile(); - if (p_dir->containsFile(file)) { - if (!closeFile(file, p_forced)) { - return false; - } - // Closed a file, so don't need to add i. - } else { - ++i; - } - } - return true; -} - -bool VEditWindow::closeFile(const VNotebook *p_notebook, bool p_forced) -{ - Q_ASSERT(p_notebook); - int i = 0; - while (i < count()) { - VEditTab *editor = getTab(i); - QPointer file = editor->getFile(); - if (p_notebook->containsFile(file)) { - if (!closeFile(file, p_forced)) { - return false; - } - // Closed a file, so don't need to add i. - } else { - ++i; - } - } - return true; -} - -bool VEditWindow::closeAllFiles(bool p_forced) -{ - int nrTab = count(); - bool ret = true; - for (int i = 0; i < nrTab; ++i) { - VEditTab *editor = getTab(0); - - VEditTabInfo tabInfo = editor->fetchTabInfo(); - VFileSessionInfo info = VFileSessionInfo::fromEditTabInfo(&tabInfo); - - if (!p_forced) { - setCurrentIndex(0); - updateTabStatus(0); - } - - // Even p_forced is true we need to delete unused images. - bool ok = editor->closeFile(p_forced); - if (ok) { - removeEditTab(0); - - m_editArea->recordClosedFile(info); - } else { - ret = false; - break; - } - } - - if (count() == 0) { - emit requestRemoveSplit(this); - } - - return ret; -} - -int VEditWindow::openFileInTab(VFile *p_file, OpenFileMode p_mode) -{ - VEditTab *editor = NULL; - switch (p_file->getDocType()) { - case DocType::Markdown: - editor = new VMdTab(p_file, m_editArea, p_mode, this); - break; - - case DocType::Html: - editor = new VHtmlTab(p_file, m_editArea, p_mode, this); - break; - - default: - V_ASSERT(false); - break; - } - - // Connect the signals. - connectEditTab(editor); - - int idx = appendEditTab(p_file, editor); - return idx; -} - -int VEditWindow::findTabByFile(const VFile *p_file) const -{ - int nrTabs = count(); - for (int i = 0; i < nrTabs; ++i) { - if (getTab(i)->getFile() == p_file) { - return i; - } - } - return -1; -} - -bool VEditWindow::closeTab(int p_index) -{ - VEditTab *editor = getTab(p_index); - Q_ASSERT(editor); - VEditTabInfo tabInfo = editor->fetchTabInfo(); - VFileSessionInfo info = VFileSessionInfo::fromEditTabInfo(&tabInfo); - bool ok = editor->closeFile(false); - if (ok) { - removeEditTab(p_index); - - m_editArea->recordClosedFile(info); - } - - // User clicks the close button. We should make this window - // to be current window. - emit getFocused(); - if (count() == 0) { - emit requestRemoveSplit(this); - } - - return ok; -} - -void VEditWindow::readFile() -{ - VEditTab *editor = getTab(currentIndex()); - Q_ASSERT(editor); - editor->readFile(); -} - -void VEditWindow::saveAndReadFile() -{ - saveFile(); - readFile(); -} - -void VEditWindow::editFile() -{ - VEditTab *editor = getTab(currentIndex()); - Q_ASSERT(editor); - editor->editFile(); -} - -void VEditWindow::saveFile() -{ - VEditTab *editor = getTab(currentIndex()); - Q_ASSERT(editor); - editor->saveFile(); -} - -void VEditWindow::updateTabStatus(int p_index) -{ - if (p_index == -1) { - p_index = currentIndex(); - } - - if (p_index == -1) { - emit tabStatusUpdated(VEditTabInfo()); - emit outlineChanged(VTableOfContent()); - emit currentHeaderChanged(VHeaderPointer()); - return; - } - - VEditTab *tab = getTab(p_index); - emit tabStatusUpdated(tab->fetchTabInfo()); - emit outlineChanged(tab->getOutline()); - emit currentHeaderChanged(tab->getCurrentHeader()); - - updateTabInfo(p_index); -} - -void VEditWindow::updateTabInfo(int p_index) -{ - static QIcon editModified = VIconUtils::tabBarSpecialIcon(":/resources/icons/editing_modified.svg"); - static QIcon edit = VIconUtils::tabBarIcon(":/resources/icons/editing.svg"); - static QIcon readModified = VIconUtils::tabBarSpecialIcon(":/resources/icons/reading_modified.svg"); - static QIcon read = VIconUtils::tabBarIcon(":/resources/icons/reading.svg"); - - VEditTab *editor = getTab(p_index); - const VFile *file = editor->getFile(); - bool editMode = editor->isEditMode(); - - setTabText(p_index, generateTabText(p_index, editor)); - setTabToolTip(p_index, generateTooltip(file)); - - QIcon icon; - if (editMode) { - icon = editor->isModified() ? editModified : edit; - } else { - icon = editor->isModified() ? readModified : read; - } - - setTabIcon(p_index, icon); -} - -void VEditWindow::updateAllTabsSequence() -{ - for (int i = 0; i < count(); ++i) { - VEditTab *editor = getTab(i); - setTabText(i, generateTabText(i, editor)); - } -} - -VTableOfContent VEditWindow::getOutline() const -{ - int idx = currentIndex(); - if (idx == -1) { - return VTableOfContent(); - } - - return getTab(idx)->getOutline(); -} - -VHeaderPointer VEditWindow::getCurrentHeader() const -{ - int idx = currentIndex(); - if (idx == -1) { - return VHeaderPointer(); - } - - return getTab(idx)->getCurrentHeader(); -} - -// Focus this windows. Try to focus current tab. -void VEditWindow::focusWindow() -{ - int idx = currentIndex(); - if (idx == -1) { - setFocus(); - emit getFocused(); - return; - } - getTab(idx)->focusTab(); -} - -void VEditWindow::handleTabbarClicked(int p_index) -{ - // Only handle the case when (p_index == currentIndex()) here - // because currentIndex() is not changed yet. If we focus window - // now, we may change the current index forcely. - if (p_index == currentIndex()) { - focusWindow(); - } -} - -void VEditWindow::handleCurrentIndexChanged(int p_index) -{ - focusWindow(); - - QWidget *wid = widget(p_index); - if (wid && (wid == m_curTabWidget)) { - return; - } - - m_lastTabWidget = m_curTabWidget; - m_curTabWidget = wid; -} - -void VEditWindow::mousePressEvent(QMouseEvent *event) -{ - focusWindow(); - QTabWidget::mousePressEvent(event); -} - -void VEditWindow::contextMenuRequested(QPoint pos) -{ - QMenu menu(this); - menu.setToolTipsVisible(true); - - if (canRemoveSplit()) { - menu.addAction(removeSplitAct); - menu.exec(this->mapToGlobal(pos)); - } -} - -void VEditWindow::tabbarContextMenuRequested(QPoint p_pos) -{ - QMenu menu(this); - menu.setToolTipsVisible(true); - - QTabBar *bar = tabBar(); - int tab = bar->tabAt(p_pos); - if (tab == -1) { - return; - } - - VEditTab *editor = getTab(tab); - VFile *file = editor->getFile(); - if (file->getType() == FileType::Note) { - // Locate to folder. - m_locateAct->setData(tab); - menu.addAction(m_locateAct); - - menu.addSeparator(); - - m_recycleBinAct->setData(tab); - menu.addAction(m_recycleBinAct); - - m_openLocationAct->setData(tab); - menu.addAction(m_openLocationAct); - - m_reloadAct->setData(tab); - menu.addAction(m_reloadAct); - - m_noteInfoAct->setData(tab); - menu.addAction(m_noteInfoAct); - } else if (file->getType() == FileType::Orphan - && !(dynamic_cast(file)->isSystemFile())) { - m_recycleBinAct->setData(tab); - menu.addAction(m_recycleBinAct); - - m_openLocationAct->setData(tab); - menu.addAction(m_openLocationAct); - - m_reloadAct->setData(tab); - menu.addAction(m_reloadAct); - - m_noteInfoAct->setData(tab); - menu.addAction(m_noteInfoAct); - } - - - int totalWin = m_editArea->windowCount(); - // When there is only one tab and one split window, there is no need to - // display these two actions. - if (totalWin > 1 || count() > 1) { - menu.addSeparator(); - m_moveLeftAct->setData(tab); - // Move one split left. - menu.addAction(m_moveLeftAct); - - m_moveRightAct->setData(tab); - // Move one split right. - menu.addAction(m_moveRightAct); - } - - // Close tab, or other tabs, or tabs to the right. - menu.addSeparator(); - m_closeTabAct->setData(tab); - menu.addAction(m_closeTabAct); - if (count() > 1) { - m_closeOthersAct->setData(tab); - menu.addAction(m_closeOthersAct); - if (tab < count() - 1) { - m_closeRightAct->setData(tab); - menu.addAction(m_closeRightAct); - } - } - - if (!menu.actions().isEmpty()) { - menu.exec(bar->mapToGlobal(p_pos)); - } -} - -void VEditWindow::tabListJump(VFile *p_file) -{ - if (!p_file) { - return; - } - - int idx = findTabByFile(p_file); - Q_ASSERT(idx >= 0); - setCurrentIndex(idx); - focusWindow(); - updateTabStatus(idx); -} - -void VEditWindow::updateSplitMenu() -{ - if (canRemoveSplit()) { - removeSplitAct->setVisible(true); - } else { - removeSplitAct->setVisible(false); - } -} - -bool VEditWindow::canRemoveSplit() -{ - QSplitter *splitter = dynamic_cast(parent()); - Q_ASSERT(splitter); - return splitter->count() > 1; -} - -void VEditWindow::handleTabOutlineChanged(const VTableOfContent &p_outline) -{ - // Only propagate it if it is current tab. - VEditTab *tab = getCurrentTab(); - if (tab) { - if (tab->getFile() == p_outline.getFile()) { - emit outlineChanged(p_outline); - } - } else { - emit outlineChanged(VTableOfContent()); - return; - } -} - -void VEditWindow::handleTabCurrentHeaderChanged(const VHeaderPointer &p_header) -{ - // Only propagate it if it is current tab. - VEditTab *tab = getCurrentTab(); - if (tab) { - if (tab->getFile() == p_header.m_file) { - emit currentHeaderChanged(p_header); - } - } else { - emit currentHeaderChanged(VHeaderPointer()); - return; - } -} - -void VEditWindow::scrollToHeader(const VHeaderPointer &p_header) -{ - VEditTab *tab = getCurrentTab(); - if (tab) { - tab->scrollToHeader(p_header); - } -} - -void VEditWindow::handleTabStatusUpdated(const VEditTabInfo &p_info) -{ - int idx = indexOf(dynamic_cast(sender())); - - if (p_info.m_type == VEditTabInfo::InfoType::All) { - updateTabInfo(idx); - updateAllTabsSequence(); - } - - if (idx == currentIndex()) { - // Current tab. Propogate its status. - emit tabStatusUpdated(p_info); - } -} - -void VEditWindow::handleTabStatusMessage(const QString &p_msg) -{ - int idx = indexOf(dynamic_cast(sender())); - if (idx == currentIndex()) { - emit statusMessage(p_msg); - } -} - -void VEditWindow::handleTabVimStatusUpdated(const VVim *p_vim) -{ - int idx = indexOf(dynamic_cast(sender())); - if (idx == currentIndex()) { - emit vimStatusUpdated(p_vim); - } -} - -void VEditWindow::updateFileInfo(const VFile *p_file, UpdateAction p_act) -{ - if (!p_file) { - return; - } - - int idx = findTabByFile(p_file); - if (idx > -1) { - updateTabStatus(idx); - getTab(idx)->handleFileOrDirectoryChange(true, p_act); - } -} - -void VEditWindow::updateDirectoryInfo(const VDirectory *p_dir, UpdateAction p_act) -{ - if (!p_dir) { - return; - } - - int nrTab = count(); - for (int i = 0; i < nrTab; ++i) { - VEditTab *editor = getTab(i); - QPointer file = editor->getFile(); - if (p_dir->containsFile(file)) { - updateTabStatus(i); - editor->handleFileOrDirectoryChange(false, p_act); - } - } -} - -void VEditWindow::updateNotebookInfo(const VNotebook *p_notebook) -{ - if (!p_notebook) { - return; - } - - int nrTab = count(); - for (int i = 0; i < nrTab; ++i) { - VEditTab *editor = getTab(i); - QPointer file = editor->getFile(); - if (p_notebook->containsFile(file)) { - updateTabStatus(i); - } - } -} - -VEditTab *VEditWindow::getCurrentTab() const -{ - int idx = currentIndex(); - if (idx == -1) { - return NULL; - } - - return getTab(idx); -} - -QVector VEditWindow::getAllTabsInfo() const -{ - int nrTab = count(); - - QVector tabs; - tabs.reserve(nrTab); - for (int i = 0; i < nrTab; ++i) { - VEditTab *editTab = getTab(i); - tabs.push_back(editTab->fetchTabInfo()); - } - - return tabs; -} - -void VEditWindow::handleLocateAct() -{ - int tab = m_locateAct->data().toInt(); - VEditTab *editor = getTab(tab); - QPointer file = editor->getFile(); - if (file->getType() == FileType::Note) { - g_mainWin->locateFile(file); - } -} - -void VEditWindow::handleMoveLeftAct() -{ - int tab = m_moveLeftAct->data().toInt(); - Q_ASSERT(tab != -1); - moveTabOneSplit(tab, false); -} - -void VEditWindow::handleMoveRightAct() -{ - int tab = m_moveRightAct->data().toInt(); - Q_ASSERT(tab != -1); - moveTabOneSplit(tab, true); -} - -void VEditWindow::moveTabOneSplit(int p_tabIdx, bool p_right) -{ - Q_ASSERT(p_tabIdx > -1 && p_tabIdx < count()); - // Add split window if needed. - if (m_editArea->windowCount() < 2) { - // Request VEditArea to split window. - splitWindow(p_right); - - // Though the signal and slot will behave like a function call. We wait - // here until the window split finished. - while (m_editArea->windowCount() < 2) { - VUtils::sleepWait(100); - } - } - - int totalWin = m_editArea->windowCount(); - int idx = m_editArea->windowIndex(this); - int newIdx = p_right ? idx + 1 : idx - 1; - if (newIdx >= totalWin) { - newIdx = 0; - } else if (newIdx < 0) { - newIdx = totalWin - 1; - } - VEditTab *editor = getTab(p_tabIdx); - // Remove it from current window. This won't close the split even if it is - // the only tab. - removeTab(p_tabIdx); - - // Disconnect all the signals. - disconnect(editor, 0, this, 0); - - m_editArea->moveTab(editor, idx, newIdx); - - // If there is no tab, remove current split. - if (count() == 0) { - emit requestRemoveSplit(this); - } -} - -void VEditWindow::moveCurrentTabOneSplit(bool p_right) -{ - int idx = currentIndex(); - if (idx == -1) { - return; - } - - moveTabOneSplit(idx, p_right); -} - -bool VEditWindow::addEditTab(QWidget *p_widget) -{ - if (!p_widget) { - return false; - } - - VEditTab *editor = dynamic_cast(p_widget); - if (!editor) { - return false; - } - - // Connect the signals. - connectEditTab(editor); - - int idx = appendEditTab(editor->getFile(), editor); - setCurrentIndex(idx); - updateTabStatus(idx); - return true; -} - -void VEditWindow::connectEditTab(const VEditTab *p_tab) -{ - connect(p_tab, &VEditTab::getFocused, - this, &VEditWindow::getFocused); - connect(p_tab, &VEditTab::outlineChanged, - this, &VEditWindow::handleTabOutlineChanged); - connect(p_tab, &VEditTab::currentHeaderChanged, - this, &VEditWindow::handleTabCurrentHeaderChanged); - connect(p_tab, &VEditTab::statusUpdated, - this, &VEditWindow::handleTabStatusUpdated); - connect(p_tab, &VEditTab::statusMessage, - this, &VEditWindow::handleTabStatusMessage); - connect(p_tab, &VEditTab::vimStatusUpdated, - this, &VEditWindow::handleTabVimStatusUpdated); - connect(p_tab, &VEditTab::closeRequested, - this, &VEditWindow::tabRequestToClose); -} - -void VEditWindow::setCurrentWindow(bool p_current) -{ - static QIcon menuCur = VIconUtils::editWindowCornerIcon(":/resources/icons/corner_menu_cur.svg"); - static QIcon tablistCur = VIconUtils::editWindowCornerIcon(":/resources/icons/corner_tablist_cur.svg"); - static QIcon menu = VIconUtils::editWindowCornerInactiveIcon(":/resources/icons/corner_menu.svg"); - static QIcon tablist = VIconUtils::editWindowCornerInactiveIcon(":/resources/icons/corner_tablist.svg"); - - if (p_current) { - rightBtn->setIcon(menuCur); - leftBtn->setIcon(tablistCur); - } else { - rightBtn->setIcon(menu); - leftBtn->setIcon(tablist); - } -} - -void VEditWindow::clearSearchedWordHighlight() -{ - int nrTab = count(); - for (int i = 0; i < nrTab; ++i) { - getTab(i)->clearSearchedWordHighlight(); - } -} - -void VEditWindow::focusNextTab(bool p_right) -{ - focusWindow(); - if (count() < 2) { - return; - } - int idx = currentIndex(); - idx = p_right ? idx + 1 : idx - 1; - if (idx < 0) { - idx = count() - 1; - } else if (idx >= count()) { - idx = 0; - } - setCurrentIndex(idx); -} - -bool VEditWindow::showOpenedFileList() -{ - if (count() == 0) { - return false; - } - - leftBtn->showMenu(); - VOpenedListMenu *menu = dynamic_cast(leftBtn->menu()); - return menu->isAccepted(); -} - -bool VEditWindow::activateTab(int p_sequence) -{ - if (p_sequence < c_tabSequenceBase || p_sequence >= (c_tabSequenceBase + count())) { - return false; - } - setCurrentIndex(p_sequence - c_tabSequenceBase); - return true; -} - -bool VEditWindow::alternateTab() -{ - if (m_lastTabWidget) { - if (-1 != indexOf(m_lastTabWidget)) { - setCurrentWidget(m_lastTabWidget); - return true; - } else { - m_lastTabWidget = NULL; - } - } - return false; -} - -VEditTab* VEditWindow::getTab(int tabIndex) const -{ - return dynamic_cast(widget(tabIndex)); -} - -void VEditWindow::dragEnterEvent(QDragEnterEvent *p_event) -{ - if (p_event->mimeData()->hasFormat("text/uri-list")) { - p_event->acceptProposedAction(); - return; - } - - QTabWidget::dragEnterEvent(p_event); -} - -void VEditWindow::dropEvent(QDropEvent *p_event) -{ - const QMimeData *mime = p_event->mimeData(); - if (mime->hasFormat("text/uri-list") && mime->hasUrls()) { - // Open external files in this edit window. - QStringList files; - QList urls = mime->urls(); - for (int i = 0; i < urls.size(); ++i) { - QString file; - if (urls[i].isLocalFile()) { - file = urls[i].toLocalFile(); - QFileInfo fi(file); - if (fi.exists() && fi.isFile()) { - file = QDir::cleanPath(fi.absoluteFilePath()); - files.append(file); - } - } - } - - if (!files.isEmpty()) { - focusWindow(); - g_mainWin->openFiles(files); - } - - p_event->acceptProposedAction(); - return; - } - - QTabWidget::dropEvent(p_event); -} - -QVector VEditWindow::getAllTabs() const -{ - int nrTab = count(); - - QVector tabs; - tabs.reserve(nrTab); - for (int i = 0; i < nrTab; ++i) { - tabs.push_back(getTab(i)); - } - - return tabs; -} - -void VEditWindow::checkFileChangeOutside() -{ - int nrTab = count(); - for (int i = 0; i < nrTab; ++i) { - getTab(i)->checkFileChangeOutside(); - } -} - -void VEditWindow::tabRequestToClose(VEditTab *p_tab) -{ - bool ok = p_tab->closeFile(false); - if (ok) { - removeTab(indexOf(p_tab)); - - // Disconnect all the signals. - disconnect(p_tab, 0, this, 0); - - p_tab->deleteLater(); - } -} diff --git a/src/veditwindow.h b/src/veditwindow.h deleted file mode 100644 index 0dc5de2c..00000000 --- a/src/veditwindow.h +++ /dev/null @@ -1,244 +0,0 @@ -#ifndef VEDITWINDOW_H -#define VEDITWINDOW_H - -#include -#include -#include -#include -#include -#include "vnotebook.h" -#include "vedittab.h" -#include "vconstants.h" -#include "vnotefile.h" - -class QPushButton; -class QActionGroup; -class VEditArea; - -class VEditWindow : public QTabWidget -{ - Q_OBJECT -public: - explicit VEditWindow(VEditArea *editArea, QWidget *parent = 0); - int findTabByFile(const VFile *p_file) const; - int openFile(VFile *p_file, OpenFileMode p_mode); - bool closeFile(const VFile *p_file, bool p_forced); - bool closeFile(const VDirectory *p_dir, bool p_forced); - bool closeFile(const VNotebook *p_notebook, bool p_forced); - void editFile(); - void saveFile(); - void readFile(); - void saveAndReadFile(); - bool closeAllFiles(bool p_forced); - - // Return outline of current tab. - VTableOfContent getOutline() const; - - // Return current header of current tab. - VHeaderPointer getCurrentHeader() const; - - // Focus to current tab's editor - void focusWindow(); - - // Scroll current tab to header @p_header. - void scrollToHeader(const VHeaderPointer &p_header); - - void updateFileInfo(const VFile *p_file, UpdateAction p_act); - - void updateDirectoryInfo(const VDirectory *p_dir, UpdateAction p_act); - - void updateNotebookInfo(const VNotebook *p_notebook); - - VEditTab *getCurrentTab() const; - - VEditTab *getTab(int tabIndex) const; - - QVector getAllTabsInfo() const; - - QVector getAllTabs() const; - - // Insert a tab with @p_widget. @p_widget is a fully initialized VEditTab. - bool addEditTab(QWidget *p_widget); - // Set whether it is the current window. - void setCurrentWindow(bool p_current); - void clearSearchedWordHighlight(); - void moveCurrentTabOneSplit(bool p_right); - void focusNextTab(bool p_right); - // Return true if the file list is shown. - bool showOpenedFileList(); - bool activateTab(int p_sequence); - // Switch to previous activated tab. - bool alternateTab(); - - // Ask tab @p_index to update its status and propogate. - // The status here means tab status, outline, current header. - // If @p_index is -1, it is current tab. - void updateTabStatus(int p_index = -1); - - // Check whether opened files have been changed outside. - void checkFileChangeOutside(); - -protected: - void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - - // To accept specific drop. - void dragEnterEvent(QDragEnterEvent *p_event) Q_DECL_OVERRIDE; - - // Drop the data. - void dropEvent(QDropEvent *p_event) Q_DECL_OVERRIDE; - -signals: - // Status of current VEditTab has update. - void tabStatusUpdated(const VEditTabInfo &p_info); - - // Requst VEditArea to split this window. - void requestSplitWindow(VEditWindow *p_window, bool p_right = true); - - void requestRemoveSplit(VEditWindow *curWindow); - // This widget or its children get the focus - void getFocused(); - - void outlineChanged(const VTableOfContent &p_outline); - - void currentHeaderChanged(const VHeaderPointer &p_header); - - // Emit when want to show message in status bar. - void statusMessage(const QString &p_msg); - - // Emit when Vim mode status changed. - void vimStatusUpdated(const VVim *p_vim); - -private slots: - // Close tab @p_index. - bool closeTab(int p_index); - - // Split this window on the right/left. - void splitWindow(bool p_right = true); - - void removeSplit(); - void handleTabbarClicked(int p_index); - void handleCurrentIndexChanged(int p_index); - void contextMenuRequested(QPoint pos); - void tabListJump(VFile *p_file); - - void handleTabOutlineChanged(const VTableOfContent &p_outline); - - void handleTabCurrentHeaderChanged(const VHeaderPointer &p_header); - - void updateSplitMenu(); - void tabbarContextMenuRequested(QPoint p_pos); - void handleLocateAct(); - void handleMoveLeftAct(); - void handleMoveRightAct(); - - // Handle the statusMessage signal of VEditTab. - void handleTabStatusMessage(const QString &p_msg); - - // Handle the vimStatusUpdated() signal of VEditTab. - void handleTabVimStatusUpdated(const VVim *p_vim); - - // Handle the statusUpdated signal of VEditTab. - void handleTabStatusUpdated(const VEditTabInfo &p_info); - - // @p_tab request to close itself. - void tabRequestToClose(VEditTab *p_tab); - -private: - void initTabActions(); - void setupCornerWidget(); - void removeEditTab(int p_index); - int insertEditTab(int p_index, VFile *p_file, QWidget *p_page); - int appendEditTab(VFile *p_file, QWidget *p_page); - int openFileInTab(VFile *p_file, OpenFileMode p_mode); - - QString generateTooltip(const VFile *p_file) const; - - QString generateTabText(int p_index, const VEditTab *p_tab) const; - - bool canRemoveSplit(); - - // Move tab at @p_tabIdx one split window. - // @p_right: move right or left. - // If there is only one split window, it will request to split current window - // and move the tab to the new split. - void moveTabOneSplit(int p_tabIdx, bool p_right); - - // Update info of tab @p_idx according to the state of the editor and file. - void updateTabInfo(int p_idx); - - // Update the sequence number of all the tabs. - void updateAllTabsSequence(); - - // Connect the signals of VEditTab to this VEditWindow. - void connectEditTab(const VEditTab *p_tab); - - VEditArea *m_editArea; - - // These two members are only used for alternateTab(). - QWidget *m_curTabWidget; - QWidget *m_lastTabWidget; - - // Button in the right corner - QPushButton *rightBtn; - // Button in the left corner - QPushButton *leftBtn; - - // Actions - QAction *splitAct; - QAction *removeSplitAct; - // Locate current note in the directory and file list - QAction *m_locateAct; - QAction *m_moveLeftAct; - QAction *m_moveRightAct; - - // Close current tab action in tab menu. - QAction *m_closeTabAct; - - // Close other tabs action in tab menu. - QAction *m_closeOthersAct; - - // Close tabs to the right in tab menu. - QAction *m_closeRightAct; - - // View and edit info about this note. - QAction *m_noteInfoAct; - - // Open the location (the folder containing this file) of this note. - QAction *m_openLocationAct; - - // Reload the note from disk. - QAction *m_reloadAct; - - // Open the recycle bin folder of this note. - QAction *m_recycleBinAct; -}; - -inline QString VEditWindow::generateTooltip(const VFile *p_file) const -{ - if (!p_file) { - return ""; - } - - // [Notebook]path - if (p_file->getType() == FileType::Note) { - const VNoteFile *tmpFile = dynamic_cast(p_file); - return QString("[%1] %2").arg(tmpFile->getNotebookName()).arg(tmpFile->fetchPath()); - } else { - return QString("%1").arg(p_file->fetchPath()); - } -} - -inline QString VEditWindow::generateTabText(int p_index, const VEditTab *p_tab) const -{ - const VFile *file = p_tab->getFile(); - if (!file) { - return ""; - } - - return QString("%1.%2%3%4").arg(QString::number(p_index + c_tabSequenceBase, 10)) - .arg(file->getName()) - .arg(file->isModifiable() ? "" : "#") - .arg(p_tab->isModified() ? "*" : ""); -} - -#endif // VEDITWINDOW_H diff --git a/src/vexporter.cpp b/src/vexporter.cpp deleted file mode 100644 index 4a76d8a3..00000000 --- a/src/vexporter.cpp +++ /dev/null @@ -1,425 +0,0 @@ -#include "vexporter.h" - -#include -#include -#include -#include -#include -#include -#include - -#ifndef QT_NO_PRINTER -#include -#include -#endif - -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "vfile.h" -#include "vwebview.h" -#include "vpreviewpage.h" -#include "vconstants.h" -#include "vnote.h" -#include "vmarkdownconverter.h" -#include "vdocument.h" - -extern VConfigManager *g_config; - -QString VExporter::s_defaultPathDir = QDir::homePath(); - -VExporter::VExporter(MarkdownConverterType p_mdType, QWidget *p_parent) - : QDialog(p_parent), m_webViewer(NULL), m_mdType(p_mdType), - m_file(NULL), m_type(ExportType::PDF), m_source(ExportSource::Invalid), - m_noteState(NoteState::NotReady), m_state(ExportState::Idle), - m_pageLayout(QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0.0, 0.0, 0.0, 0.0))), - m_exported(false) -{ - initMarkdownTemplate(); - - setupUI(); -} - -void VExporter::initMarkdownTemplate() -{ - m_htmlTemplate = VUtils::generateHtmlTemplate(m_mdType, true); -} - -void VExporter::setupUI() -{ - m_infoLabel = new QLabel(); - m_infoLabel->setWordWrap(true); - - // Target file path. - QLabel *pathLabel = new QLabel(tr("Target &path:")); - m_pathEdit = new QLineEdit(); - pathLabel->setBuddy(m_pathEdit); - m_browseBtn = new QPushButton(tr("&Browse")); - connect(m_browseBtn, &QPushButton::clicked, - this, &VExporter::handleBrowseBtnClicked); - - // Page layout. - QLabel *layoutLabel = new QLabel(tr("Page layout:")); - m_layoutLabel = new QLabel(); - m_layoutBtn = new QPushButton(tr("&Settings")); - -#ifndef QT_NO_PRINTER - connect(m_layoutBtn, &QPushButton::clicked, - this, &VExporter::handleLayoutBtnClicked); -#else - m_layoutBtn->hide(); -#endif - - // Progress. - m_proLabel = new QLabel(this); - m_proBar = new QProgressBar(this); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - m_openBtn = m_btnBox->addButton(tr("Open File Location"), QDialogButtonBox::ActionRole); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &VExporter::startExport); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &VExporter::cancelExport); - connect(m_openBtn, &QPushButton::clicked, this, &VExporter::openTargetPath); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - m_pathEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QGridLayout *mainLayout = new QGridLayout(); - mainLayout->addWidget(m_infoLabel, 0, 0, 1, 3); - mainLayout->addWidget(pathLabel, 1, 0); - mainLayout->addWidget(m_pathEdit, 1, 1); - mainLayout->addWidget(m_browseBtn, 1, 2); - mainLayout->addWidget(layoutLabel, 2, 0); - mainLayout->addWidget(m_layoutLabel, 2, 1); - mainLayout->addWidget(m_layoutBtn, 2, 2); - mainLayout->addWidget(m_proLabel, 3, 1, 1, 2); - mainLayout->addWidget(m_proBar, 4, 1, 1, 2); - mainLayout->addWidget(m_btnBox, 5, 1, 1, 2); - - m_proLabel->hide(); - m_proBar->hide(); - - setLayout(mainLayout); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setWindowTitle(tr("Export Note")); - - m_openBtn->hide(); - - updatePageLayoutLabel(); -} - -static QString exportTypeStr(ExportType p_type) -{ - if (p_type == ExportType::PDF) { - return "PDF"; - } else { - return "HTML"; - } -} - -void VExporter::handleBrowseBtnClicked() -{ - QFileInfo fi(getFilePath()); - QString fileType = m_type == ExportType::PDF ? - tr("Portable Document Format (*.pdf)") : - tr("WebPage, Complete (*.html)"); - QString path = QFileDialog::getSaveFileName(this, tr("Export As"), - fi.absoluteFilePath(), - fileType); - if (path.isEmpty()) { - return; - } - - setFilePath(path); - s_defaultPathDir = VUtils::basePathFromPath(path); - - m_openBtn->hide(); -} - -void VExporter::handleLayoutBtnClicked() -{ -#ifndef QT_NO_PRINTER - QPrinter printer; - printer.setPageLayout(m_pageLayout); - - QPageSetupDialog dlg(&printer, this); - if (dlg.exec() != QDialog::Accepted) { - return; - } - - m_pageLayout.setPageSize(printer.pageLayout().pageSize()); - m_pageLayout.setOrientation(printer.pageLayout().orientation()); - - updatePageLayoutLabel(); -#endif -} - -void VExporter::updatePageLayoutLabel() -{ - m_layoutLabel->setText(QString("%1, %2").arg(m_pageLayout.pageSize().name()) - .arg(m_pageLayout.orientation() == QPageLayout::Portrait ? - tr("Portrait") : tr("Landscape"))); -} - -QString VExporter::getFilePath() const -{ - return QDir::cleanPath(m_pathEdit->text()); -} - -void VExporter::setFilePath(const QString &p_path) -{ - m_pathEdit->setText(QDir::toNativeSeparators(p_path)); -} - -void VExporter::exportNote(VFile *p_file, ExportType p_type) -{ - m_file = p_file; - m_type = p_type; - m_source = ExportSource::Note; - - if (!m_file || m_file->getDocType() != DocType::Markdown) { - // Do not support non-Markdown note now. - m_btnBox->button(QDialogButtonBox::Ok)->setEnabled(false); - return; - } - - m_infoLabel->setText(tr("Export note %2 as %3.") - .arg(g_config->c_dataTextStyle) - .arg(m_file->getName()) - .arg(exportTypeStr(p_type))); - - setWindowTitle(tr("Export As %1").arg(exportTypeStr(p_type))); - - setFilePath(QDir(s_defaultPathDir).filePath(QFileInfo(p_file->fetchPath()).baseName() + - "." + exportTypeStr(p_type).toLower())); -} - -void VExporter::initWebViewer(VFile *p_file) -{ - V_ASSERT(!m_webViewer); - - m_webViewer = new VWebView(p_file, this); - m_webViewer->hide(); - VPreviewPage *page = new VPreviewPage(m_webViewer); - m_webViewer->setPage(page); - - connect(page, &VPreviewPage::loadFinished, - this, &VExporter::handleLoadFinished); - - VDocument *document = new VDocument(p_file, m_webViewer); - connect(document, &VDocument::logicsFinished, - this, &VExporter::handleLogicsFinished); - - QWebChannel *channel = new QWebChannel(m_webViewer); - channel->registerObject(QStringLiteral("content"), document); - page->setWebChannel(channel); - - // Need to generate HTML using Hoedown. - if (m_mdType == MarkdownConverterType::Hoedown) { - VMarkdownConverter mdConverter; - QString toc; - QString html = mdConverter.generateHtml(p_file->getContent(), - g_config->getMarkdownExtensions(), - toc); - document->setHtml(html); - } - - m_webViewer->setHtml(m_htmlTemplate, p_file->getBaseUrl()); -} - -void VExporter::clearWebViewer() -{ - if (m_webViewer) { - delete m_webViewer; - m_webViewer = NULL; - } -} - -void VExporter::handleLogicsFinished() -{ - Q_ASSERT(!(m_noteState & NoteState::WebLogicsReady)); - m_noteState = NoteState(m_noteState | NoteState::WebLogicsReady); -} - -void VExporter::handleLoadFinished(bool p_ok) -{ - Q_ASSERT(!(m_noteState & NoteState::WebLoadFinished)); - m_noteState = NoteState(m_noteState | NoteState::WebLoadFinished); - - if (!p_ok) { - m_noteState = NoteState(m_noteState | NoteState::Failed); - } -} - -void VExporter::clearNoteState() -{ - m_noteState = NoteState::NotReady; -} - -bool VExporter::isNoteStateReady() const -{ - return m_noteState == NoteState::Ready; -} - -bool VExporter::isNoteStateFailed() const -{ - return m_noteState & NoteState::Failed; -} - -void VExporter::startExport() -{ - QPushButton *cancelBtn = m_btnBox->button(QDialogButtonBox::Cancel); - - if (m_exported) { - cancelBtn->show(); - m_exported = false; - accept(); - } - - int exportedNum = 0; - enableUserInput(false); - V_ASSERT(m_state == ExportState::Idle); - m_state = ExportState::Busy; - - m_openBtn->hide(); - - if (m_source == ExportSource::Note) { - V_ASSERT(m_file); - bool isOpened = m_file->isOpened(); - if (!isOpened && !m_file->open()) { - goto exit; - } - - clearNoteState(); - initWebViewer(m_file); - - // Update progress info. - m_proLabel->setText(tr("Exporting %1").arg(m_file->getName())); - m_proBar->setEnabled(true); - m_proBar->setMinimum(0); - m_proBar->setMaximum(100); - m_proBar->reset(); - m_proLabel->show(); - m_proBar->show(); - - while (!isNoteStateReady()) { - VUtils::sleepWait(100); - if (m_proBar->value() < 70) { - m_proBar->setValue(m_proBar->value() + 1); - } - - if (m_state == ExportState::Cancelled) { - goto exit; - } - - if (isNoteStateFailed()) { - m_state = ExportState::Failed; - goto exit; - } - } - - // Wait to ensure Web side is really ready. - VUtils::sleepWait(200); - - if (m_state == ExportState::Cancelled) { - goto exit; - } - - m_proBar->setValue(80); - - bool exportRet = exportToPDF(m_webViewer, getFilePath(), m_pageLayout); - - clearNoteState(); - - if (!isOpened) { - m_file->close(); - } - - if (exportRet) { - m_proBar->setValue(100); - m_state = ExportState::Successful; - exportedNum++; - } else { - m_proBar->setEnabled(false); - m_state = ExportState::Failed; - } - } - -exit: - clearWebViewer(); - - m_proLabel->setText(""); - m_proLabel->hide(); - enableUserInput(true); - - if (m_state == ExportState::Cancelled) { - reject(); - } - - if (exportedNum) { - m_exported = true; - m_openBtn->show(); - cancelBtn->hide(); - } - - m_state = ExportState::Idle; -} - -void VExporter::cancelExport() -{ - if (m_state == ExportState::Idle) { - reject(); - } else { - m_state = ExportState::Cancelled; - } -} - -bool VExporter::exportToPDF(VWebView *p_webViewer, const QString &p_filePath, - const QPageLayout &p_layout) -{ - int pdfPrinted = 0; - p_webViewer->page()->printToPdf([&, this](const QByteArray &p_result) { - if (p_result.isEmpty() || this->m_state == ExportState::Cancelled) { - pdfPrinted = -1; - return; - } - - V_ASSERT(!p_filePath.isEmpty()); - - QFile file(p_filePath); - - if (!file.open(QFile::WriteOnly)) { - pdfPrinted = -1; - return; - } - - file.write(p_result.data(), p_result.size()); - file.close(); - - pdfPrinted = 1; - }, p_layout); - - while (pdfPrinted == 0) { - VUtils::sleepWait(100); - - if (m_state == ExportState::Cancelled) { - break; - } - } - - return pdfPrinted == 1; -} - -void VExporter::enableUserInput(bool p_enabled) -{ - m_btnBox->button(QDialogButtonBox::Ok)->setEnabled(p_enabled); - m_pathEdit->setEnabled(p_enabled); - m_browseBtn->setEnabled(p_enabled); - m_layoutBtn->setEnabled(p_enabled); -} - -void VExporter::openTargetPath() const -{ - QUrl url = QUrl::fromLocalFile(VUtils::basePathFromPath(getFilePath())); - QDesktopServices::openUrl(url); -} diff --git a/src/vexporter.h b/src/vexporter.h deleted file mode 100644 index a51d79a6..00000000 --- a/src/vexporter.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef VEXPORTER_H -#define VEXPORTER_H - -#include -#include -#include -#include "vconfigmanager.h" - -class VWebView; -class VFile; -class QLineEdit; -class QLabel; -class QDialogButtonBox; -class QPushButton; -class QProgressBar; - -enum class ExportType -{ - PDF = 0, - HTML -}; - -class VExporter : public QDialog -{ - Q_OBJECT -public: - explicit VExporter(MarkdownConverterType p_mdType = MarkdownIt, QWidget *p_parent = 0); - - void exportNote(VFile *p_file, ExportType p_type); - -private slots: - void handleBrowseBtnClicked(); - void handleLayoutBtnClicked(); - void startExport(); - void cancelExport(); - void handleLogicsFinished(); - void handleLoadFinished(bool p_ok); - void openTargetPath() const; - -private: - enum class ExportSource - { - Note = 0, - Directory, - Notebook, - Invalid - }; - - enum class ExportState - { - Idle = 0, - Cancelled, - Busy, - Failed, - Successful - }; - - enum NoteState - { - NotReady = 0, - WebLogicsReady = 0x1, - WebLoadFinished = 0x2, - Ready = 0x3, - Failed = 0x4 - }; - - void setupUI(); - - void initMarkdownTemplate(); - - void updatePageLayoutLabel(); - - void setFilePath(const QString &p_path); - - QString getFilePath() const; - - void initWebViewer(VFile *p_file); - - void clearWebViewer(); - - void enableUserInput(bool p_enabled); - - bool exportToPDF(VWebView *p_webViewer, const QString &p_filePath, const QPageLayout &p_layout); - - void clearNoteState(); - bool isNoteStateReady() const; - bool isNoteStateFailed() const; - - // Will be allocated and free for each conversion. - VWebView *m_webViewer; - - MarkdownConverterType m_mdType; - QString m_htmlTemplate; - VFile *m_file; - ExportType m_type; - ExportSource m_source; - NoteState m_noteState; - - ExportState m_state; - - QLabel *m_infoLabel; - QLineEdit *m_pathEdit; - QPushButton *m_browseBtn; - QLabel *m_layoutLabel; - QPushButton *m_layoutBtn; - QDialogButtonBox *m_btnBox; - QPushButton *m_openBtn; - - // Progress label and bar. - QLabel *m_proLabel; - QProgressBar *m_proBar; - - QPageLayout m_pageLayout; - - // Whether a PDF has been exported. - bool m_exported; - - // The default directory. - static QString s_defaultPathDir; -}; - -#endif // VEXPORTER_H diff --git a/src/vfile.cpp b/src/vfile.cpp deleted file mode 100644 index 37547dab..00000000 --- a/src/vfile.cpp +++ /dev/null @@ -1,210 +0,0 @@ -#include "vfile.h" - -#include -#include -#include -#include -#include -#include -#include "utils/vutils.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -const QString VFile::c_backupFileHeadMagic = "vnote_backup_file_826537664"; - -VFile::VFile(QObject *p_parent, - const QString &p_name, - FileType p_type, - bool p_modifiable, - QDateTime p_createdTimeUtc, - QDateTime p_modifiedTimeUtc) - : QObject(p_parent), - m_name(p_name), - m_opened(false), - m_docType(VUtils::docTypeFromName(p_name)), - m_type(p_type), - m_modifiable(p_modifiable), - m_createdTimeUtc(p_createdTimeUtc), - m_modifiedTimeUtc(p_modifiedTimeUtc) -{ -} - -VFile::~VFile() -{ -} - -bool VFile::open() -{ - if (m_opened) { - return true; - } - - Q_ASSERT(!m_name.isEmpty()); - Q_ASSERT(m_content.isEmpty()); - - QString filePath = fetchPath(); - Q_ASSERT(QFileInfo::exists(filePath)); - m_content = VUtils::readFileFromDisk(filePath); - m_lastModified = QFileInfo(filePath).lastModified(); - m_opened = true; - return true; -} - -void VFile::close() -{ - if (!m_opened) { - return; - } - - m_content.clear(); - if (!m_backupName.isEmpty()) { - VUtils::deleteFile(fetchBackupFilePath()); - m_backupName.clear(); - } - - m_opened = false; -} - -bool VFile::save() -{ - Q_ASSERT(m_opened); - Q_ASSERT(m_modifiable); - - bool ret = VUtils::writeFileToDisk(fetchPath(), m_content); - if (ret) { - m_lastModified = QFileInfo(fetchPath()).lastModified(); - m_modifiedTimeUtc = QDateTime::currentDateTimeUtc(); - } - - return ret; -} - -QUrl VFile::getBaseUrl() const -{ - // Need to judge the path: Url, local file, resource file. - QUrl baseUrl; - QString basePath = fetchBasePath(); - QFileInfo pathInfo(basePath); - if (pathInfo.exists()) { - if (pathInfo.isNativePath()) { - // Local file. - baseUrl = QUrl::fromLocalFile(basePath + QDir::separator()); - } else { - // Resource file. - baseUrl = QUrl("qrc" + basePath + QDir::separator()); - } - } else { - // Url. - baseUrl = QUrl(basePath + QDir::separator()); - } - - return baseUrl; -} - -bool VFile::isInternalImageFolder(const QString &p_path) const -{ - return VUtils::equalPath(VUtils::basePathFromPath(p_path), - fetchBasePath()) - || VUtils::equalPath(p_path, fetchImageFolderPath()); -} - -bool VFile::isChangedOutside() const -{ - QDateTime lm = QFileInfo(fetchPath()).lastModified(); - return lm != m_lastModified; -} - -void VFile::reload() -{ - Q_ASSERT(m_opened); - - QString filePath = fetchPath(); - Q_ASSERT(QFileInfo::exists(filePath)); - m_content = VUtils::readFileFromDisk(filePath); - m_lastModified = QFileInfo(filePath).lastModified(); -} - -QString VFile::backupFileOfPreviousSession() const -{ - Q_ASSERT(m_modifiable && m_backupName.isEmpty()); - - QString basePath = QDir(fetchBasePath()).filePath(g_config->getBackupDirectory()); - QDir dir(basePath); - - QStringList files = getPotentialBackupFiles(basePath); - foreach (const QString &file, files) { - QString filePath = dir.filePath(file); - if (isBackupFile(filePath)) { - return filePath; - } - } - - return QString(); -} - -QString VFile::fetchBackupFilePath() -{ - QString basePath = QDir(fetchBasePath()).filePath(g_config->getBackupDirectory()); - QDir dir(basePath); - - if (m_backupName.isEmpty()) { - m_backupName = VUtils::getFileNameWithSequence(basePath, - m_name + g_config->getBackupExtension(), - true); - - m_lastBackupFilePath = dir.filePath(m_backupName); - } else { - QString filePath = dir.filePath(m_backupName); - if (filePath != m_lastBackupFilePath) { - // File has been moved. - // Delete the original backup file if it still exists. - VUtils::deleteFile(m_lastBackupFilePath); - - m_lastBackupFilePath = filePath; - } - } - - return m_lastBackupFilePath; -} - -QStringList VFile::getPotentialBackupFiles(const QString &p_dir) const -{ - QString nameFilter = QString("%1*%2").arg(m_name).arg(g_config->getBackupExtension()); - QStringList files = QDir(p_dir).entryList(QStringList(nameFilter), - QDir::Files - | QDir::Hidden - | QDir::NoSymLinks - | QDir::NoDotAndDotDot); - return files; -} - -bool VFile::isBackupFile(const QString &p_file) const -{ - QFile file(p_file); - if (!file.open(QFile::ReadOnly | QIODevice::Text)) { - return false; - } - - QTextStream st(&file); - QString head = st.readLine(); - return head == fetchBackupFileHead(); -} - -QString VFile::fetchBackupFileHead() const -{ - return c_backupFileHeadMagic + " " + fetchPath(); -} - -bool VFile::writeBackupFile(const QString &p_content) -{ - return VUtils::writeFileToDisk(fetchBackupFilePath(), - fetchBackupFileHead() + "\n" + p_content); -} - -QString VFile::readBackupFile(const QString &p_file) -{ - const QString content = VUtils::readFileFromDisk(p_file); - int idx = content.indexOf("\n"); - return content.mid(idx + 1); -} diff --git a/src/vfile.h b/src/vfile.h deleted file mode 100644 index b1cbb36e..00000000 --- a/src/vfile.h +++ /dev/null @@ -1,185 +0,0 @@ -#ifndef VFILE_H -#define VFILE_H - -#include -#include -#include -#include -#include "vconstants.h" - -// VFile is an abstract class representing a file in VNote. -class VFile : public QObject -{ - Q_OBJECT -public: - VFile(QObject *p_parent, - const QString &p_name, - FileType p_type, - bool p_modifiable, - QDateTime p_createdTimeUtc, - QDateTime p_modifiedTimeUtc); - - virtual ~VFile(); - - // Open the file to load content into m_content. - // Init m_opened, and m_content. - virtual bool open(); - - // Close the file. - // Clear m_content, m_opened. - virtual void close(); - - // Save m_content to the file. - virtual bool save(); - - // Reload content from disk. - virtual void reload(); - - const QString &getName() const; - - DocType getDocType() const; - - bool isModifiable() const; - - bool isOpened() const; - - FileType getType() const; - - const QString &getContent() const; - - void setContent(const QString &p_content); - - // Get the absolute full path of the file. - virtual QString fetchPath() const = 0; - - // Get the absolute full path of the directory containing the file. - virtual QString fetchBasePath() const = 0; - - // The path of the image folder to store images of this file. - virtual QString fetchImageFolderPath() const = 0; - - // Return the base URL for this file when loaded in VWebView. - QUrl getBaseUrl() const; - - // Whether the directory @p_path is an internal image folder of this file. - // It is true only when the folder is in the same directory as the parent - // directory of this file or equals to fetchImageFolderPath(). - bool isInternalImageFolder(const QString &p_path) const; - - // Whether use a relative image folder. - virtual bool useRelativeImageFolder() const = 0; - - // Return the image folder part in an image link. - virtual QString getImageFolderInLink() const = 0; - - QDateTime getCreatedTimeUtc() const; - - QDateTime getModifiedTimeUtc() const; - - // Whether this file was changed outside VNote. - bool isChangedOutside() const; - - // Return backup file of previous session if there exists one. - QString backupFileOfPreviousSession() const; - - // Write @p_content to backup file. - bool writeBackupFile(const QString &p_content); - - QString readBackupFile(const QString &p_file); - -protected: - // Name of this file. - QString m_name; - - // Whether this file has been opened (content loaded). - bool m_opened; - - // DocType of this file: Html, Markdown. - DocType m_docType; - - // Content of this file. - QString m_content; - - // FileType of this file: Note, Orphan. - FileType m_type; - - // Whether this file is modifiable. - bool m_modifiable; - - // UTC time when creating this file. - QDateTime m_createdTimeUtc; - - // UTC time of last modification to this file in VNote. - QDateTime m_modifiedTimeUtc; - - // Last modified date and local time when the file is last modified - // corresponding to m_content. - QDateTime m_lastModified; - - // Name of the backup file. - QString m_backupName; - - // Used to identify file path change. - QString m_lastBackupFilePath; - -private: - // Fetch backup file path. - QString fetchBackupFilePath(); - - QStringList getPotentialBackupFiles(const QString &p_dir) const; - - // Read the file content to check if it is a backup file. - bool isBackupFile(const QString &p_file) const; - - QString fetchBackupFileHead() const; - - static const QString c_backupFileHeadMagic; -}; - -inline const QString &VFile::getName() const -{ - return m_name; -} - -inline DocType VFile::getDocType() const -{ - return m_docType; -} - -inline bool VFile::isModifiable() const -{ - return m_modifiable; -} - -inline bool VFile::isOpened() const -{ - return m_opened; -} - -inline FileType VFile::getType() const -{ - return m_type; -} - -inline const QString &VFile::getContent() const -{ - Q_ASSERT(m_opened); - return m_content; -} - -inline void VFile::setContent(const QString &p_content) -{ - m_content = p_content; -} - -inline QDateTime VFile::getCreatedTimeUtc() const -{ - return m_createdTimeUtc; -} - -inline QDateTime VFile::getModifiedTimeUtc() const -{ - return m_modifiedTimeUtc; -} - -#endif // VFILE_H diff --git a/src/vfilelist.cpp b/src/vfilelist.cpp deleted file mode 100644 index 7970e4d0..00000000 --- a/src/vfilelist.cpp +++ /dev/null @@ -1,1023 +0,0 @@ -#include -#include -#include -#include "vfilelist.h" -#include "vconfigmanager.h" -#include "dialog/vnewfiledialog.h" -#include "dialog/vfileinfodialog.h" -#include "vnote.h" -#include "veditarea.h" -#include "utils/vutils.h" -#include "vnotefile.h" -#include "vconfigmanager.h" -#include "vmdeditor.h" -#include "vmdtab.h" -#include "dialog/vconfirmdeletiondialog.h" -#include "dialog/vsortdialog.h" -#include "vmainwindow.h" -#include "utils/vimnavigationforwidget.h" -#include "utils/viconutils.h" - -extern VConfigManager *g_config; -extern VNote *g_vnote; -extern VMainWindow *g_mainWin; - -const QString VFileList::c_infoShortcutSequence = "F2"; -const QString VFileList::c_copyShortcutSequence = "Ctrl+C"; -const QString VFileList::c_cutShortcutSequence = "Ctrl+X"; -const QString VFileList::c_pasteShortcutSequence = "Ctrl+V"; - -VFileList::VFileList(QWidget *parent) - : QWidget(parent), VNavigationMode() -{ - setupUI(); - initShortcuts(); - initActions(); -} - -void VFileList::setupUI() -{ - fileList = new QListWidget(this); - fileList->setContextMenuPolicy(Qt::CustomContextMenu); - fileList->setSelectionMode(QAbstractItemView::ExtendedSelection); - fileList->setObjectName("FileList"); - fileList->setAttribute(Qt::WA_MacShowFocusRect, false); - - QVBoxLayout *mainLayout = new QVBoxLayout; - mainLayout->addWidget(fileList); - mainLayout->setContentsMargins(0, 0, 0, 0); - - connect(fileList, &QListWidget::customContextMenuRequested, - this, &VFileList::contextMenuRequested); - connect(fileList, &QListWidget::itemClicked, - this, &VFileList::handleItemClicked); - - setLayout(mainLayout); -} - -void VFileList::initShortcuts() -{ - QShortcut *infoShortcut = new QShortcut(QKeySequence(c_infoShortcutSequence), this); - infoShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(infoShortcut, &QShortcut::activated, - this, [this](){ - fileInfo(); - }); - - QShortcut *copyShortcut = new QShortcut(QKeySequence(c_copyShortcutSequence), this); - copyShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(copyShortcut, &QShortcut::activated, - this, [this](){ - copySelectedFiles(); - }); - - QShortcut *cutShortcut = new QShortcut(QKeySequence(c_cutShortcutSequence), this); - cutShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(cutShortcut, &QShortcut::activated, - this, [this](){ - cutSelectedFiles(); - }); - - QShortcut *pasteShortcut = new QShortcut(QKeySequence(c_pasteShortcutSequence), this); - pasteShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(pasteShortcut, &QShortcut::activated, - this, [this](){ - pasteFilesFromClipboard(); - }); -} - -void VFileList::initActions() -{ - newFileAct = new QAction(VIconUtils::menuIcon(":/resources/icons/create_note.svg"), - tr("&New Note"), this); - QString shortcutStr = VUtils::getShortcutText(g_config->getShortcutKeySequence("NewNote")); - if (!shortcutStr.isEmpty()) { - newFileAct->setText(tr("&New Note\t%1").arg(shortcutStr)); - } - - newFileAct->setToolTip(tr("Create a note in current folder")); - connect(newFileAct, SIGNAL(triggered(bool)), - this, SLOT(newFile())); - - m_openInReadAct = new QAction(VIconUtils::menuIcon(":/resources/icons/reading.svg"), - tr("&Open In Read Mode"), this); - m_openInReadAct->setToolTip(tr("Open current note in read mode")); - connect(m_openInReadAct, &QAction::triggered, - this, [this]() { - QListWidgetItem *item = fileList->currentItem(); - if (item) { - emit fileClicked(getVFile(item), OpenFileMode::Read, true); - } - }); - - m_openInEditAct = new QAction(VIconUtils::menuIcon(":/resources/icons/editing.svg"), - tr("Open In &Edit Mode"), this); - m_openInEditAct->setToolTip(tr("Open current note in edit mode")); - connect(m_openInEditAct, &QAction::triggered, - this, [this]() { - QListWidgetItem *item = fileList->currentItem(); - if (item) { - emit fileClicked(getVFile(item), OpenFileMode::Edit, true); - } - }); - - deleteFileAct = new QAction(VIconUtils::menuDangerIcon(":/resources/icons/delete_note.svg"), - tr("&Delete"), this); - deleteFileAct->setToolTip(tr("Delete selected note")); - connect(deleteFileAct, SIGNAL(triggered(bool)), - this, SLOT(deleteSelectedFiles())); - - fileInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/note_info.svg"), - tr("&Info\t%1").arg(VUtils::getShortcutText(c_infoShortcutSequence)), this); - fileInfoAct->setToolTip(tr("View and edit current note's information")); - connect(fileInfoAct, SIGNAL(triggered(bool)), - this, SLOT(fileInfo())); - - copyAct = new QAction(VIconUtils::menuIcon(":/resources/icons/copy.svg"), - tr("&Copy\t%1").arg(VUtils::getShortcutText(c_copyShortcutSequence)), this); - copyAct->setToolTip(tr("Copy selected notes")); - connect(copyAct, &QAction::triggered, - this, &VFileList::copySelectedFiles); - - cutAct = new QAction(VIconUtils::menuIcon(":/resources/icons/cut.svg"), - tr("C&ut\t%1").arg(VUtils::getShortcutText(c_cutShortcutSequence)), this); - cutAct->setToolTip(tr("Cut selected notes")); - connect(cutAct, &QAction::triggered, - this, &VFileList::cutSelectedFiles); - - pasteAct = new QAction(VIconUtils::menuIcon(":/resources/icons/paste.svg"), - tr("&Paste\t%1").arg(VUtils::getShortcutText(c_pasteShortcutSequence)), this); - pasteAct->setToolTip(tr("Paste notes in current folder")); - connect(pasteAct, &QAction::triggered, - this, &VFileList::pasteFilesFromClipboard); - - m_openLocationAct = new QAction(tr("&Open Note Location"), this); - m_openLocationAct->setToolTip(tr("Open the folder containing this note in operating system")); - connect(m_openLocationAct, &QAction::triggered, - this, &VFileList::openFileLocation); - - m_sortAct = new QAction(VIconUtils::menuIcon(":/resources/icons/sort.svg"), - tr("&Sort"), - this); - m_sortAct->setToolTip(tr("Sort notes in this folder manually")); - connect(m_sortAct, &QAction::triggered, - this, &VFileList::sortItems); - - initOpenWithMenu(); -} - -void VFileList::setDirectory(VDirectory *p_directory) -{ - // QPointer will be set to NULL automatically once the directory was deleted. - // If the last directory is deleted, m_directory and p_directory will both - // be NULL. - if (m_directory == p_directory) { - if (!m_directory) { - fileList->clear(); - } - - return; - } - - m_directory = p_directory; - if (!m_directory) { - fileList->clear(); - return; - } - - updateFileList(); -} - -void VFileList::updateFileList() -{ - fileList->clear(); - if (!m_directory->open()) { - return; - } - - const QVector &files = m_directory->getFiles(); - for (int i = 0; i < files.size(); ++i) { - VNoteFile *file = files[i]; - insertFileListItem(file); - } -} - -void VFileList::fileInfo() -{ - QList items = fileList->selectedItems(); - if (items.size() == 1) { - fileInfo(getVFile(items[0])); - } -} - -void VFileList::openFileLocation() const -{ - QList items = fileList->selectedItems(); - if (items.size() == 1) { - QUrl url = QUrl::fromLocalFile(getVFile(items[0])->fetchBasePath()); - QDesktopServices::openUrl(url); - } -} - -void VFileList::fileInfo(VNoteFile *p_file) -{ - if (!p_file) { - return; - } - - VDirectory *dir = p_file->getDirectory(); - QString curName = p_file->getName(); - VFileInfoDialog dialog(tr("Note Information"), "", dir, p_file, this); - if (dialog.exec() == QDialog::Accepted) { - QString name = dialog.getNameInput(); - if (name == curName) { - return; - } - - if (!p_file->rename(name)) { - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Fail to rename note %2.") - .arg(g_config->c_dataTextStyle).arg(curName), "", - QMessageBox::Ok, QMessageBox::Ok, this); - return; - } - - QListWidgetItem *item = findItem(p_file); - if (item) { - fillItem(item, p_file); - } - - emit fileUpdated(p_file, UpdateAction::InfoChanged); - } -} - -void VFileList::fillItem(QListWidgetItem *p_item, const VNoteFile *p_file) -{ - qulonglong ptr = (qulonglong)p_file; - p_item->setData(Qt::UserRole, ptr); - p_item->setToolTip(p_file->getName()); - p_item->setText(p_file->getName()); - - V_ASSERT(sizeof(p_file) <= sizeof(ptr)); -} - -QListWidgetItem* VFileList::insertFileListItem(VNoteFile *file, bool atFront) -{ - V_ASSERT(file); - QListWidgetItem *item = new QListWidgetItem(); - fillItem(item, file); - - if (atFront) { - fileList->insertItem(0, item); - } else { - fileList->addItem(item); - } - - // Qt seems not to update the QListWidget correctly. Manually force it to repaint. - fileList->update(); - return item; -} - -void VFileList::removeFileListItem(VNoteFile *p_file) -{ - if (!p_file) { - return; - } - - QListWidgetItem *item = findItem(p_file); - if (!item) { - return; - } - - int row = fileList->row(item); - Q_ASSERT(row >= 0); - - fileList->takeItem(row); - delete item; - - // Qt seems not to update the QListWidget correctly. Manually force it to repaint. - fileList->update(); -} - -void VFileList::newFile() -{ - if (!m_directory) { - return; - } - - QList suffixes = g_config->getDocSuffixes()[(int)DocType::Markdown]; - QString defaultSuf; - QString suffixStr; - for (auto const & suf : suffixes) { - suffixStr += (suffixStr.isEmpty() ? suf : "/" + suf); - if (defaultSuf.isEmpty() || suf == "md") { - defaultSuf = suf; - } - } - - QString info = tr("Create a note in %2.") - .arg(g_config->c_dataTextStyle).arg(m_directory->getName()); - info = info + "
    " + tr("Note with name ending with \"%1\" will be treated as Markdown type.") - .arg(suffixStr); - QString defaultName = QString("new_note.%1").arg(defaultSuf); - defaultName = VUtils::getFileNameWithSequence(m_directory->fetchPath(), - defaultName, - true); - VNewFileDialog dialog(tr("Create Note"), info, defaultName, m_directory, this); - if (dialog.exec() == QDialog::Accepted) { - VNoteFile *file = m_directory->createFile(dialog.getNameInput()); - if (!file) { - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Fail to create note %2.") - .arg(g_config->c_dataTextStyle).arg(dialog.getNameInput()), "", - QMessageBox::Ok, QMessageBox::Ok, this); - return; - } - - // Whether need to move the cursor to the end. - bool moveCursorEnd = false; - // Content needed to insert into the new file, title/template. - QString insertContent; - if (dialog.getInsertTitleInput() && file->getDocType() == DocType::Markdown) { - // Insert title. - insertContent = QString("# %1\n").arg(QFileInfo(file->getName()).completeBaseName()); - } - - if (dialog.isTemplateUsed()) { - Q_ASSERT(insertContent.isEmpty()); - insertContent = dialog.getTemplate(); - } - - if (!insertContent.isEmpty()) { - if (!file->open()) { - qWarning() << "fail to open newly-created note" << file->getName(); - } else { - Q_ASSERT(file->getContent().isEmpty()); - file->setContent(insertContent); - if (!file->save()) { - qWarning() << "fail to write to newly-created note" << file->getName(); - } else { - if (dialog.getInsertTitleInput()) { - moveCursorEnd = true; - } - } - - file->close(); - } - } - - QVector items = updateFileListAdded(); - Q_ASSERT(items.size() == 1); - fileList->setCurrentItem(items[0], QItemSelectionModel::ClearAndSelect); - // Qt seems not to update the QListWidget correctly. Manually force it to repaint. - fileList->update(); - - // Open it in edit mode - emit fileCreated(file, OpenFileMode::Edit, true); - - // Move cursor down if content has been inserted. - if (moveCursorEnd) { - const VMdTab *tab = dynamic_cast(editArea->getCurrentTab()); - if (tab) { - VMdEditor *edit = tab->getEditor(); - if (edit && edit->getFile() == file) { - QTextCursor cursor = edit->textCursor(); - cursor.movePosition(QTextCursor::End); - edit->setTextCursor(cursor); - } - } - } - } -} - -QVector VFileList::updateFileListAdded() -{ - QVector ret; - const QVector &files = m_directory->getFiles(); - for (int i = 0; i < files.size(); ++i) { - VNoteFile *file = files[i]; - if (i >= fileList->count()) { - QListWidgetItem *item = insertFileListItem(file, false); - ret.append(item); - } else { - VNoteFile *itemFile = getVFile(fileList->item(i)); - if (itemFile != file) { - QListWidgetItem *item = insertFileListItem(file, false); - ret.append(item); - } - } - } - - return ret; -} - -void VFileList::deleteSelectedFiles() -{ - QList items = fileList->selectedItems(); - Q_ASSERT(!items.isEmpty()); - - QVector files; - for (auto const & item : items) { - files.push_back(getVFile(item)); - } - - deleteFiles(files); -} - -// @p_file may or may not be listed in VFileList -void VFileList::deleteFile(VNoteFile *p_file) -{ - if (!p_file) { - return; - } - - QVector files(1, p_file); - deleteFiles(files); -} - -void VFileList::deleteFiles(const QVector &p_files) -{ - if (p_files.isEmpty()) { - return; - } - - QVector items; - for (auto const & file : p_files) { - items.push_back(ConfirmItemInfo(file->getName(), - file->fetchPath(), - file->fetchPath(), - (void *)file)); - } - - QString text = tr("Are you sure to delete these notes?"); - - QString info = tr("WARNING: " - "VNote will delete notes as well as all " - "their images and attachments managed by VNote. " - "Deleted files could be found in the recycle " - "bin of these notes.
    " - "Click \"Cancel\" to leave them untouched.
    " - "The operation is IRREVERSIBLE!") - .arg(g_config->c_warningTextStyle); - - VConfirmDeletionDialog dialog(tr("Confirm Deleting Notes"), - text, - info, - items, - false, - false, - false, - this); - if (dialog.exec()) { - items = dialog.getConfirmedItems(); - QVector files; - for (auto const & item : items) { - files.push_back((VNoteFile *)item.m_data); - } - - int nrDeleted = 0; - for (auto file : files) { - editArea->closeFile(file, true); - - // Remove the item before deleting it totally, or file will be invalid. - removeFileListItem(file); - - QString errMsg; - QString fileName = file->getName(); - QString filePath = file->fetchPath(); - if (!VNoteFile::deleteFile(file, &errMsg)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to delete note %2.
    " - "Please check %3 and manually delete it.") - .arg(g_config->c_dataTextStyle) - .arg(fileName) - .arg(filePath), - errMsg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } else { - Q_ASSERT(errMsg.isEmpty()); - ++nrDeleted; - } - } - - if (nrDeleted > 0) { - g_mainWin->showStatusMessage(tr("%1 %2 deleted") - .arg(nrDeleted) - .arg(nrDeleted > 1 ? tr("notes") : tr("note"))); - } - } -} - -void VFileList::contextMenuRequested(QPoint pos) -{ - QListWidgetItem *item = fileList->itemAt(pos); - QMenu menu(this); - menu.setToolTipsVisible(true); - - if (!m_directory) { - return; - } - - if (item && fileList->selectedItems().size() == 1) { - VNoteFile *file = getVFile(item); - if (file) { - if (file->getDocType() == DocType::Markdown) { - menu.addAction(m_openInReadAct); - menu.addAction(m_openInEditAct); - } - - menu.addMenu(m_openWithMenu); - menu.addSeparator(); - } - } - - menu.addAction(newFileAct); - - if (fileList->count() > 1) { - menu.addAction(m_sortAct); - } - - if (item) { - menu.addSeparator(); - menu.addAction(deleteFileAct); - menu.addAction(copyAct); - menu.addAction(cutAct); - } - - if (pasteAvailable()) { - if (!item) { - menu.addSeparator(); - } - - menu.addAction(pasteAct); - } - - if (item) { - menu.addSeparator(); - menu.addAction(m_openLocationAct); - - if (fileList->selectedItems().size() == 1) { - menu.addAction(fileInfoAct); - } - } - - menu.exec(fileList->mapToGlobal(pos)); -} - -QListWidgetItem* VFileList::findItem(const VNoteFile *p_file) -{ - if (!p_file || p_file->getDirectory() != m_directory) { - return NULL; - } - - int nrChild = fileList->count(); - for (int i = 0; i < nrChild; ++i) { - QListWidgetItem *item = fileList->item(i); - if (p_file == getVFile(item)) { - return item; - } - } - - return NULL; -} - -void VFileList::handleItemClicked(QListWidgetItem *currentItem) -{ - Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers(); - if (modifiers != Qt::NoModifier) { - return; - } - - if (!currentItem) { - emit fileClicked(NULL); - return; - } - - // Qt seems not to update the QListWidget correctly. Manually force it to repaint. - fileList->update(); - emit fileClicked(getVFile(currentItem), g_config->getNoteOpenMode()); -} - -bool VFileList::importFiles(const QStringList &p_files, QString *p_errMsg) -{ - if (p_files.isEmpty()) { - return false; - } - - bool ret = true; - Q_ASSERT(m_directory && m_directory->isOpened()); - QString dirPath = m_directory->fetchPath(); - QDir dir(dirPath); - - int nrImported = 0; - for (int i = 0; i < p_files.size(); ++i) { - const QString &file = p_files[i]; - - QFileInfo fi(file); - if (!fi.exists() || !fi.isFile()) { - VUtils::addErrMsg(p_errMsg, tr("Skip importing non-exist file %1.") - .arg(file)); - ret = false; - continue; - } - - QString name = VUtils::fileNameFromPath(file); - Q_ASSERT(!name.isEmpty()); - name = VUtils::getFileNameWithSequence(dirPath, name, true); - QString targetFilePath = dir.filePath(name); - bool ret = VUtils::copyFile(file, targetFilePath, false); - if (!ret) { - VUtils::addErrMsg(p_errMsg, tr("Fail to copy file %1 as %2.") - .arg(file) - .arg(targetFilePath)); - ret = false; - continue; - } - - VNoteFile *destFile = m_directory->addFile(name, -1); - if (destFile) { - ++nrImported; - qDebug() << "imported" << file << "as" << targetFilePath; - } else { - VUtils::addErrMsg(p_errMsg, tr("Fail to add the note %1 to target folder's configuration.") - .arg(file)); - ret = false; - continue; - } - } - - qDebug() << "imported" << nrImported << "files"; - - updateFileList(); - - return ret; -} - -void VFileList::copySelectedFiles(bool p_isCut) -{ - QList items = fileList->selectedItems(); - if (items.isEmpty()) { - return; - } - - QJsonArray files; - for (int i = 0; i < items.size(); ++i) { - VNoteFile *file = getVFile(items[i]); - files.append(file->fetchPath()); - } - - QJsonObject clip; - clip[ClipboardConfig::c_magic] = getNewMagic(); - clip[ClipboardConfig::c_type] = (int)ClipboardOpType::CopyFile; - clip[ClipboardConfig::c_isCut] = p_isCut; - clip[ClipboardConfig::c_files] = files; - - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(QJsonDocument(clip).toJson(QJsonDocument::Compact)); - - qDebug() << "copied files info" << clipboard->text(); - - int cnt = files.size(); - g_mainWin->showStatusMessage(tr("%1 %2 %3") - .arg(cnt) - .arg(cnt > 1 ? tr("notes") : tr("note")) - .arg(p_isCut ? tr("cut") : tr("copied"))); -} - -void VFileList::cutSelectedFiles() -{ - copySelectedFiles(true); -} - -void VFileList::pasteFilesFromClipboard() -{ - if (!pasteAvailable()) { - return; - } - - QJsonObject obj = VUtils::clipboardToJson(); - QJsonArray files = obj[ClipboardConfig::c_files].toArray(); - bool isCut = obj[ClipboardConfig::c_isCut].toBool(); - QVector filesToPaste(files.size()); - for (int i = 0; i < files.size(); ++i) { - filesToPaste[i] = files[i].toString(); - } - - pasteFiles(m_directory, filesToPaste, isCut); - - QClipboard *clipboard = QApplication::clipboard(); - clipboard->clear(); -} - -void VFileList::pasteFiles(VDirectory *p_destDir, - const QVector &p_files, - bool p_isCut) -{ - if (!p_destDir || p_files.isEmpty()) { - return; - } - - int nrPasted = 0; - for (int i = 0; i < p_files.size(); ++i) { - VNoteFile *file = g_vnote->getInternalFile(p_files[i]); - if (!file) { - qWarning() << "Copied file is not an internal note" << p_files[i]; - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to paste note %2.") - .arg(g_config->c_dataTextStyle) - .arg(p_files[i]), - tr("VNote could not find this note in any notebook."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - - continue; - } - - QString fileName = file->getName(); - if (file->getDirectory() == p_destDir) { - if (p_isCut) { - qDebug() << "skip one note to cut and paste in the same folder" << fileName; - continue; - } - - // Copy and paste in the same folder. - // We do not allow this if the note contains local images. - if (file->getDocType() == DocType::Markdown) { - QVector images = VUtils::fetchImagesFromMarkdownFile(file, - ImageLink::LocalRelativeInternal); - if (!images.isEmpty()) { - qDebug() << "skip one note with internal images to copy and paste in the same folder" - << fileName; - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to copy note %2.") - .arg(g_config->c_dataTextStyle) - .arg(p_files[i]), - tr("VNote does not allow copy and paste notes with internal images " - "in the same folder."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - continue; - } - } - - // Rename it to xxx_copy.md. - fileName = VUtils::generateCopiedFileName(file->fetchBasePath(), - fileName, - true); - } else { - // Rename it to xxx_copy.md if needed. - fileName = VUtils::generateCopiedFileName(p_destDir->fetchPath(), - fileName, - true); - } - - QString msg; - VNoteFile *destFile = NULL; - bool ret = VNoteFile::copyFile(p_destDir, - fileName, - file, - p_isCut, - &destFile, - &msg); - if (!ret) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to copy note %2.") - .arg(g_config->c_dataTextStyle) - .arg(p_files[i]), - msg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - if (destFile) { - ++nrPasted; - emit fileUpdated(destFile, p_isCut ? UpdateAction::Moved : UpdateAction::InfoChanged); - } - } - - qDebug() << "pasted" << nrPasted << "files"; - if (nrPasted > 0) { - g_mainWin->showStatusMessage(tr("%1 %2 pasted") - .arg(nrPasted) - .arg(nrPasted > 1 ? tr("notes") : tr("note"))); - } - - updateFileList(); - getNewMagic(); -} - -void VFileList::keyPressEvent(QKeyEvent *p_event) -{ - if (VimNavigationForWidget::injectKeyPressEventForVim(fileList, - p_event)) { - return; - } - - if (p_event->key() == Qt::Key_Return) { - QListWidgetItem *item = fileList->currentItem(); - if (item) { - handleItemClicked(item); - } - } - - QWidget::keyPressEvent(p_event); -} - -void VFileList::focusInEvent(QFocusEvent * /* p_event */) -{ - fileList->setFocus(); -} - -bool VFileList::locateFile(const VNoteFile *p_file) -{ - if (p_file) { - if (p_file->getDirectory() != m_directory) { - return false; - } - - QListWidgetItem *item = findItem(p_file); - if (item) { - fileList->setCurrentItem(item, QItemSelectionModel::ClearAndSelect); - return true; - } - } - - return false; -} - -void VFileList::showNavigation() -{ - VNavigationMode::showNavigation(fileList); -} - -bool VFileList::handleKeyNavigation(int p_key, bool &p_succeed) -{ - static bool secondKey = false; - return VNavigationMode::handleKeyNavigation(fileList, secondKey, p_key, p_succeed); -} - -int VFileList::getNewMagic() -{ - m_magicForClipboard = (int)QDateTime::currentDateTime().toTime_t(); - m_magicForClipboard |= qrand(); - - return m_magicForClipboard; -} - -bool VFileList::checkMagic(int p_magic) const -{ - return m_magicForClipboard == p_magic; -} - -bool VFileList::pasteAvailable() const -{ - QJsonObject obj = VUtils::clipboardToJson(); - if (obj.isEmpty()) { - return false; - } - - if (!obj.contains(ClipboardConfig::c_type)) { - return false; - } - - ClipboardOpType type = (ClipboardOpType)obj[ClipboardConfig::c_type].toInt(); - if (type != ClipboardOpType::CopyFile) { - return false; - } - - if (!obj.contains(ClipboardConfig::c_magic) - || !obj.contains(ClipboardConfig::c_isCut) - || !obj.contains(ClipboardConfig::c_files)) { - return false; - } - - int magic = obj[ClipboardConfig::c_magic].toInt(); - if (!checkMagic(magic)) { - return false; - } - - QJsonArray files = obj[ClipboardConfig::c_files].toArray(); - return !files.isEmpty(); -} - -void VFileList::sortItems() -{ - const QVector &files = m_directory->getFiles(); - if (files.size() < 2) { - return; - } - - VSortDialog dialog(tr("Sort Notes"), - tr("Sort notes in folder %2 " - "in the configuration file.") - .arg(g_config->c_dataTextStyle) - .arg(m_directory->getName()), - this); - QTreeWidget *tree = dialog.getTreeWidget(); - tree->clear(); - tree->setColumnCount(3); - QStringList headers; - headers << tr("Name") << tr("Created Time") << tr("Modified Time"); - tree->setHeaderLabels(headers); - - for (int i = 0; i < files.size(); ++i) { - const VNoteFile *file = files[i]; - QString createdTime = VUtils::displayDateTime(file->getCreatedTimeUtc().toLocalTime()); - QString modifiedTime = VUtils::displayDateTime(file->getModifiedTimeUtc().toLocalTime()); - QStringList cols; - cols << file->getName() << createdTime << modifiedTime; - QTreeWidgetItem *item = new QTreeWidgetItem(tree, cols); - - item->setData(0, Qt::UserRole, i); - } - - dialog.treeUpdated(); - - if (dialog.exec()) { - QVector data = dialog.getSortedData(); - Q_ASSERT(data.size() == files.size()); - QVector sortedIdx(data.size(), -1); - for (int i = 0; i < data.size(); ++i) { - sortedIdx[i] = data[i].toInt(); - } - - qDebug() << "sort files" << sortedIdx; - if (!m_directory->sortFiles(sortedIdx)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to sort notes in folder %2.") - .arg(g_config->c_dataTextStyle) - .arg(m_directory->getName()), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - updateFileList(); - } -} - -void VFileList::initOpenWithMenu() -{ - m_openWithMenu = new QMenu(tr("Open With"), this); - m_openWithMenu->setToolTipsVisible(true); - - auto programs = g_config->getExternalEditors(); - for (auto const & pa : programs) { - QAction *act = new QAction(pa.first, this); - act->setToolTip(tr("Open current note with %1").arg(pa.first)); - act->setStatusTip(pa.second); - act->setData(pa.second); - connect(act, &QAction::triggered, - this, &VFileList::handleOpenWithActionTriggered); - - m_openWithMenu->addAction(act); - } - - QAction *defaultAct = new QAction(tr("System's Default Program"), this); - defaultAct->setToolTip(tr("Open current note with system's default program")); - connect(defaultAct, &QAction::triggered, - this, [this]() { - QListWidgetItem *item = fileList->currentItem(); - if (item) { - VNoteFile *file = getVFile(item); - if (file - && (!editArea->isFileOpened(file) || editArea->closeFile(file, false))) { - QUrl url = QUrl::fromLocalFile(file->fetchPath()); - QDesktopServices::openUrl(url); - } - } - }); - - m_openWithMenu->addAction(defaultAct); -} - -void VFileList::handleOpenWithActionTriggered() -{ - QAction *act = static_cast(sender()); - QString cmd = act->data().toString(); - - QListWidgetItem *item = fileList->currentItem(); - if (item) { - VNoteFile *file = getVFile(item); - if (file - && (!editArea->isFileOpened(file) || editArea->closeFile(file, false))) { - cmd.replace("%0", file->fetchPath()); - QProcess *process = new QProcess(this); - connect(process, static_cast(&QProcess::finished), - process, &QProcess::deleteLater); - process->start(cmd); - qDebug() << "open with" << cmd << "process" << process->processId(); - } - } -} diff --git a/src/vfilelist.h b/src/vfilelist.h deleted file mode 100644 index b8923068..00000000 --- a/src/vfilelist.h +++ /dev/null @@ -1,210 +0,0 @@ -#ifndef VFILELIST_H -#define VFILELIST_H - -#include -#include -#include -#include -#include -#include -#include -#include "vnotebook.h" -#include "vconstants.h" -#include "vdirectory.h" -#include "vnotefile.h" -#include "vnavigationmode.h" - -class QAction; -class VNote; -class QListWidget; -class QPushButton; -class VEditArea; -class QFocusEvent; -class QLabel; -class QMenu; - -class VFileList : public QWidget, public VNavigationMode -{ - Q_OBJECT -public: - explicit VFileList(QWidget *parent = 0); - - // Import external files @p_files to current directory. - // Only copy the files itself. - bool importFiles(const QStringList &p_files, QString *p_errMsg = NULL); - - inline void setEditArea(VEditArea *editArea); - - // View and edit information of @p_file. - void fileInfo(VNoteFile *p_file); - - // Delete file @p_file. - // It is not necessary that @p_file exists in the list. - void deleteFile(VNoteFile *p_file); - - // Locate @p_file in the list widget. - bool locateFile(const VNoteFile *p_file); - - const VDirectory *currentDirectory() const; - - QWidget *getContentWidget() const; - - // Implementations for VNavigationMode. - void showNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - -public slots: - // Set VFileList to display content of @p_directory directory. - void setDirectory(VDirectory *p_directory); - - // Create a note. - void newFile(); - -signals: - void fileClicked(VNoteFile *p_file, - OpenFileMode p_mode = OpenFileMode::Read, - bool p_forceMode = false); - - void fileCreated(VNoteFile *p_file, - OpenFileMode p_mode = OpenFileMode::Read, - bool p_forceMode = false); - - void fileUpdated(const VNoteFile *p_file, UpdateAction p_act); - -private slots: - void contextMenuRequested(QPoint pos); - void handleItemClicked(QListWidgetItem *currentItem); - - // View and edit information of selected file. - // Valid only when there is only one selected file. - void fileInfo(); - - // Open the folder containing selected file in system's file browser. - // Valid only when there is only one selected file. - void openFileLocation() const; - - // Copy selected files to clipboard. - // Will put a Json string into the clipboard which contains the information - // about copied files. - void copySelectedFiles(bool p_isCut = false); - - void cutSelectedFiles(); - - // Paste files from clipboard. - void pasteFilesFromClipboard(); - - // Delete selected files. - void deleteSelectedFiles(); - - // Delete files @p_files. - void deleteFiles(const QVector &p_files); - - // Sort files in this list. - void sortItems(); - - // Hanlde Open With action's triggered signal. - void handleOpenWithActionTriggered(); - -protected: - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - - void focusInEvent(QFocusEvent *p_event) Q_DECL_OVERRIDE; - -private: - void setupUI(); - - // Init shortcuts. - void initShortcuts(); - - // Clear and re-fill the list widget according to m_directory. - void updateFileList(); - - // Insert a new item into the list widget. - // @file: the file represented by the new item. - // @atFront: insert at the front or back of the list widget. - QListWidgetItem *insertFileListItem(VNoteFile *file, bool atFront = false); - - // Remove and delete item related to @p_file from list widget. - void removeFileListItem(VNoteFile *p_file); - - // Init actions. - void initActions(); - - // Return the corresponding QListWidgetItem of @p_file. - QListWidgetItem *findItem(const VNoteFile *p_file); - - // Paste files given path by @p_files to destination directory @p_destDir. - void pasteFiles(VDirectory *p_destDir, - const QVector &p_files, - bool p_isCut); - - // New items have been added to direcotry. Update file list accordingly. - QVector updateFileListAdded(); - - inline QPointer getVFile(QListWidgetItem *p_item) const; - - // Fill the info of @p_item according to @p_file. - void fillItem(QListWidgetItem *p_item, const VNoteFile *p_file); - - // Generate new magic to m_magicForClipboard. - int getNewMagic(); - - // Check if @p_magic equals to m_magicForClipboard. - bool checkMagic(int p_magic) const; - - // Check if there are files in clipboard available to paste. - bool pasteAvailable() const; - - // Init Open With menu. - void initOpenWithMenu(); - - VEditArea *editArea; - QListWidget *fileList; - QPointer m_directory; - - // Magic number for clipboard operations. - int m_magicForClipboard; - - // Actions - QAction *m_openInReadAct; - QAction *m_openInEditAct; - QAction *newFileAct; - QAction *deleteFileAct; - QAction *fileInfoAct; - QAction *copyAct; - QAction *cutAct; - QAction *pasteAct; - QAction *m_openLocationAct; - QAction *m_sortAct; - - // Context sub-menu of Open With. - QMenu *m_openWithMenu; - - static const QString c_infoShortcutSequence; - static const QString c_copyShortcutSequence; - static const QString c_cutShortcutSequence; - static const QString c_pasteShortcutSequence; -}; - -inline void VFileList::setEditArea(VEditArea *editArea) -{ - this->editArea = editArea; -} - -inline QPointer VFileList::getVFile(QListWidgetItem *p_item) const -{ - Q_ASSERT(p_item); - return (VNoteFile *)p_item->data(Qt::UserRole).toULongLong(); -} - -inline const VDirectory *VFileList::currentDirectory() const -{ - return m_directory; -} - -inline QWidget *VFileList::getContentWidget() const -{ - return fileList; -} - -#endif // VFILELIST_H diff --git a/src/vfilesessioninfo.cpp b/src/vfilesessioninfo.cpp deleted file mode 100644 index bdffad1f..00000000 --- a/src/vfilesessioninfo.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "vfilesessioninfo.h" - -#include - -#include "vedittabinfo.h" -#include "vtableofcontent.h" -#include "vedittab.h" - - -VFileSessionInfo::VFileSessionInfo() - : m_mode(OpenFileMode::Read), - m_headerIndex(-1), - m_cursorBlockNumber(-1), - m_cursorPositionInBlock(-1) -{ -} - -VFileSessionInfo::VFileSessionInfo(const QString &p_file, - OpenFileMode p_mode) - : m_file(p_file), - m_mode(p_mode), - m_headerIndex(-1), - m_cursorBlockNumber(-1), - m_cursorPositionInBlock(-1) -{ -} - -// Fetch VFileSessionInfo from @p_tabInfo. -VFileSessionInfo VFileSessionInfo::fromEditTabInfo(const VEditTabInfo *p_tabInfo) -{ - Q_ASSERT(p_tabInfo); - VEditTab *tab = p_tabInfo->m_editTab; - VFileSessionInfo info(tab->getFile()->fetchPath(), - tab->isEditMode() ? OpenFileMode::Edit : OpenFileMode::Read); - info.m_headerIndex = p_tabInfo->m_headerIndex; - info.m_cursorBlockNumber = p_tabInfo->m_cursorBlockNumber; - info.m_cursorPositionInBlock = p_tabInfo->m_cursorPositionInBlock; - - return info; -} - -void VFileSessionInfo::toEditTabInfo(VEditTabInfo *p_tabInfo) const -{ - p_tabInfo->m_headerIndex = m_headerIndex; - p_tabInfo->m_cursorBlockNumber = m_cursorBlockNumber; - p_tabInfo->m_cursorPositionInBlock = m_cursorPositionInBlock; -} - -VFileSessionInfo VFileSessionInfo::fromSettings(const QSettings *p_settings) -{ - VFileSessionInfo info; - info.m_file = p_settings->value(FileSessionConfig::c_file).toString(); - int tmpMode = p_settings->value(FileSessionConfig::c_mode).toInt(); - if (tmpMode >= (int)OpenFileMode::Read && tmpMode < (int)OpenFileMode::Invalid) { - info.m_mode = (OpenFileMode)tmpMode; - } else { - info.m_mode = OpenFileMode::Read; - } - - info.m_headerIndex = p_settings->value(FileSessionConfig::c_headerIndex).toInt(); - info.m_cursorBlockNumber = p_settings->value(FileSessionConfig::c_cursorBlockNumber).toInt(); - info.m_cursorPositionInBlock = p_settings->value(FileSessionConfig::c_cursorPositionInBlock).toInt(); - - return info; -} - -void VFileSessionInfo::toSettings(QSettings *p_settings) const -{ - p_settings->setValue(FileSessionConfig::c_file, m_file); - p_settings->setValue(FileSessionConfig::c_mode, (int)m_mode); - p_settings->setValue(FileSessionConfig::c_headerIndex, m_headerIndex); - p_settings->setValue(FileSessionConfig::c_cursorBlockNumber, m_cursorBlockNumber); - p_settings->setValue(FileSessionConfig::c_cursorPositionInBlock, m_cursorPositionInBlock); -} diff --git a/src/vfilesessioninfo.h b/src/vfilesessioninfo.h deleted file mode 100644 index f0fd8673..00000000 --- a/src/vfilesessioninfo.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef VFILESESSIONINFO_H -#define VFILESESSIONINFO_H - -#include "vconstants.h" - -struct VEditTabInfo; -class QSettings; - -namespace FileSessionConfig -{ - static const QString c_file = "file"; - static const QString c_mode = "mode"; - - // Index in outline of the anchor. - static const QString c_headerIndex = "header_index"; - - static const QString c_cursorBlockNumber = "cursor_block_number"; - static const QString c_cursorPositionInBlock = "cursor_position_in_block"; -} - -// Information about an opened file (session). -class VFileSessionInfo -{ -public: - VFileSessionInfo(); - - VFileSessionInfo(const QString &p_file, - OpenFileMode p_mode); - - // Fetch VFileSessionInfo from @p_tabInfo. - static VFileSessionInfo fromEditTabInfo(const VEditTabInfo *p_tabInfo); - - // Fill corresponding fields of @p_tabInfo. - void toEditTabInfo(VEditTabInfo *p_tabInfo) const; - - // Fetch VFileSessionInfo from @p_settings. - static VFileSessionInfo fromSettings(const QSettings *p_settings); - - void toSettings(QSettings *p_settings) const; - - // Absolute path of the file. - QString m_file; - - // Mode of this file in this session. - OpenFileMode m_mode; - - // Index in outline of the header. - int m_headerIndex; - - // Block number of cursor block. - int m_cursorBlockNumber; - - // Position in block of cursor. - int m_cursorPositionInBlock; -}; - -#endif // VFILESESSIONINFO_H diff --git a/src/vhtmltab.cpp b/src/vhtmltab.cpp deleted file mode 100644 index 0d0aad61..00000000 --- a/src/vhtmltab.cpp +++ /dev/null @@ -1,281 +0,0 @@ -#include -#include -#include "vhtmltab.h" -#include "vedit.h" -#include "utils/vutils.h" -#include "vconfigmanager.h" -#include "vnotebook.h" -#include "dialog/vfindreplacedialog.h" -#include "veditarea.h" -#include "vconstants.h" - -extern VConfigManager *g_config; - -VHtmlTab::VHtmlTab(VFile *p_file, VEditArea *p_editArea, - OpenFileMode p_mode, QWidget *p_parent) - : VEditTab(p_file, p_editArea, p_parent) -{ - V_ASSERT(m_file->getDocType() == DocType::Html); - - m_file->open(); - - setupUI(); - - if (p_mode == OpenFileMode::Edit) { - showFileEditMode(); - } else { - showFileReadMode(); - } -} - -void VHtmlTab::setupUI() -{ - m_editor = new VEdit(m_file, this); - connect(m_editor, &VEdit::textChanged, - this, &VHtmlTab::updateStatus); - connect(m_editor, &VEdit::saveAndRead, - this, &VHtmlTab::saveAndRead); - connect(m_editor, &VEdit::discardAndRead, - this, &VHtmlTab::discardAndRead); - connect(m_editor, &VEdit::editNote, - this, &VHtmlTab::editFile); - connect(m_editor, &VEdit::statusMessage, - this, &VEditTab::statusMessage); - connect(m_editor, &VEdit::vimStatusUpdated, - this, &VEditTab::vimStatusUpdated); - - m_editor->reloadFile(); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(m_editor); - mainLayout->setContentsMargins(0, 0, 0, 0); - setLayout(mainLayout); -} - -void VHtmlTab::showFileReadMode() -{ - m_isEditMode = false; - - m_editor->setReadOnly(true); - - updateStatus(); -} - -void VHtmlTab::showFileEditMode() -{ - m_isEditMode = true; - - m_editor->beginEdit(); - m_editor->setFocus(); - - updateStatus(); -} - -bool VHtmlTab::closeFile(bool p_forced) -{ - if (p_forced && m_isEditMode) { - // Discard buffer content - m_editor->reloadFile(); - m_editor->endEdit(); - - showFileReadMode(); - } else { - readFile(); - } - - return !m_isEditMode; -} - -void VHtmlTab::editFile() -{ - if (m_isEditMode) { - return; - } - - showFileEditMode(); -} - -void VHtmlTab::readFile() -{ - if (!m_isEditMode) { - return; - } - - if (m_editor && isModified()) { - // Prompt to save the changes. - bool modifiable = m_file->isModifiable(); - int ret = VUtils::showMessage(QMessageBox::Information, - tr("Information"), - tr("Note %2 has been modified.") - .arg(g_config->c_dataTextStyle).arg(m_file->getName()), - tr("Do you want to save your changes?"), - modifiable ? (QMessageBox::Save - | QMessageBox::Discard - | QMessageBox::Cancel) - : (QMessageBox::Discard - | QMessageBox::Cancel), - modifiable ? QMessageBox::Save - : QMessageBox::Cancel, - this); - switch (ret) { - case QMessageBox::Save: - if (!saveFile()) { - return; - } - - V_FALLTHROUGH; - - case QMessageBox::Discard: - m_editor->reloadFile(); - break; - - case QMessageBox::Cancel: - // Nothing to do if user cancel this action - return; - - default: - Q_ASSERT(false); - return; - } - } - - if (m_editor) { - m_editor->endEdit(); - } - - showFileReadMode(); -} - -bool VHtmlTab::saveFile() -{ - if (!m_isEditMode || !isModified()) { - return true; - } - - QString filePath = m_file->fetchPath(); - - if (!m_file->isModifiable()) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Could not modify a read-only note %2.") - .arg(g_config->c_dataTextStyle).arg(filePath), - tr("Please save your changes to other notes manually."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - return false; - } - - // Make sure the file already exists. Temporary deal with cases when user delete or move - // a file. - if (!QFileInfo::exists(filePath)) { - qWarning() << filePath << "being written has been removed"; - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), tr("Fail to save note."), - tr("File %2 being written has been removed.") - .arg(g_config->c_dataTextStyle).arg(filePath), - QMessageBox::Ok, QMessageBox::Ok, this); - return false; - } - - m_editor->saveFile(); - bool ret = m_file->save(); - if (!ret) { - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), tr("Fail to save note."), - tr("Fail to write to disk when saving a note. Please try it again."), - QMessageBox::Ok, QMessageBox::Ok, this); - m_editor->setModified(true); - } else { - m_fileDiverged = false; - m_checkFileChange = true; - } - - updateStatus(); - - return ret; -} - -bool VHtmlTab::isModified() const -{ - return m_editor->isModified() || m_fileDiverged; -} - -void VHtmlTab::saveAndRead() -{ - saveFile(); - readFile(); -} - -void VHtmlTab::discardAndRead() -{ - readFile(); -} - -void VHtmlTab::insertImage() -{ -} - -void VHtmlTab::findText(const QString &p_text, uint p_options, bool p_peek, - bool p_forward) -{ - if (p_peek) { - m_editor->peekText(p_text, p_options); - } else { - m_editor->findText(p_text, p_options, p_forward); - } -} - -void VHtmlTab::replaceText(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext) -{ - if (m_isEditMode) { - m_editor->replaceText(p_text, p_options, p_replaceText, p_findNext); - } -} - -void VHtmlTab::replaceTextAll(const QString &p_text, uint p_options, - const QString &p_replaceText) -{ - if (m_isEditMode) { - m_editor->replaceTextAll(p_text, p_options, p_replaceText); - } -} - -QString VHtmlTab::getSelectedText() const -{ - QTextCursor cursor = m_editor->textCursor(); - return cursor.selectedText(); -} - -void VHtmlTab::clearSearchedWordHighlight() -{ - m_editor->clearSearchedWordHighlight(); -} - -void VHtmlTab::zoom(bool /* p_zoomIn */, qreal /* p_step */) -{ -} - -void VHtmlTab::focusChild() -{ - m_editor->setFocus(); -} - -void VHtmlTab::requestUpdateVimStatus() -{ - m_editor->requestUpdateVimStatus(); -} - -bool VHtmlTab::restoreFromTabInfo(const VEditTabInfo &p_info) -{ - if (p_info.m_editTab != this) { - return false; - } - - return true; -} - -void VHtmlTab::reload() -{ - m_editor->reloadFile(); - updateStatus(); -} diff --git a/src/vhtmltab.h b/src/vhtmltab.h deleted file mode 100644 index e28fe673..00000000 --- a/src/vhtmltab.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef VHTMLTAB_H -#define VHTMLTAB_H - -#include -#include -#include "vedittab.h" -#include "vconstants.h" - -class VEdit; - -class VHtmlTab : public VEditTab -{ - Q_OBJECT - -public: - VHtmlTab(VFile *p_file, VEditArea *p_editArea, OpenFileMode p_mode, QWidget *p_parent = 0); - - // Close current tab. - // @p_forced: if true, discard the changes. - bool closeFile(bool p_forced) Q_DECL_OVERRIDE; - - // Enter read mode. - // Will prompt user to save the changes. - void readFile() Q_DECL_OVERRIDE; - - // Save file. - bool saveFile() Q_DECL_OVERRIDE; - - bool isModified() const Q_DECL_OVERRIDE; - - void insertImage() Q_DECL_OVERRIDE; - - // Search @p_text in current note. - void findText(const QString &p_text, uint p_options, bool p_peek, - bool p_forward = true) Q_DECL_OVERRIDE; - - // Replace @p_text with @p_replaceText in current note. - void replaceText(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext) Q_DECL_OVERRIDE; - - void replaceTextAll(const QString &p_text, uint p_options, - const QString &p_replaceText) Q_DECL_OVERRIDE; - - QString getSelectedText() const Q_DECL_OVERRIDE; - - void clearSearchedWordHighlight() Q_DECL_OVERRIDE; - - void requestUpdateVimStatus() Q_DECL_OVERRIDE; - - void reload() Q_DECL_OVERRIDE; - -public slots: - // Enter edit mode. - void editFile() Q_DECL_OVERRIDE; - -private slots: - // m_editor requests to save changes and enter read mode. - void saveAndRead(); - - // m_editor requests to discard changes and enter read mode. - void discardAndRead(); - -private: - // Setup UI. - void setupUI(); - - // Show the file content in read mode. - void showFileReadMode(); - - // Show the file content in edit mode. - void showFileEditMode(); - - // Called to zoom in/out content. - void zoom(bool p_zoomIn, qreal p_step = 0.25) Q_DECL_OVERRIDE; - - // Focus the proper child widget. - void focusChild() Q_DECL_OVERRIDE; - - // Restore from @p_fino. - // Return true if succeed. - bool restoreFromTabInfo(const VEditTabInfo &p_info) Q_DECL_OVERRIDE; - - VEdit *m_editor; -}; -#endif // VHTMLTAB_H diff --git a/src/vimageresourcemanager.cpp b/src/vimageresourcemanager.cpp deleted file mode 100644 index b4eeb6f3..00000000 --- a/src/vimageresourcemanager.cpp +++ /dev/null @@ -1,132 +0,0 @@ -#include "vimageresourcemanager.h" - -#include - -#include "vplaintextedit.h" - - -VImageResourceManager::VImageResourceManager() - : m_maximumImageWidth(0) -{ -} - -void VImageResourceManager::addImage(const QString &p_name, - const QPixmap &p_image) -{ - m_images.insert(p_name, p_image); -} - -bool VImageResourceManager::contains(const QString &p_name) const -{ - return m_images.contains(p_name); -} - -void VImageResourceManager::updateBlockInfos(const QVector &p_blocksInfo, - int p_maximumWidth) -{ - QSet usedImages; - m_blocksInfo.clear(); - m_maximumImageWidth = 0; - - for (auto const & info : p_blocksInfo) { - auto it = m_blocksInfo.insert(info.m_blockNumber, info); - VBlockImageInfo &newInfo = it.value(); - auto imageIt = m_images.find(newInfo.m_imageName); - if (imageIt != m_images.end()) { - // Fill the width and height. - newInfo.m_imageWidth = imageIt.value().width(); - newInfo.m_imageHeight = imageIt.value().height(); - adjustWidthAndHeight(newInfo, p_maximumWidth); - updateMaximumImageWidth(newInfo, p_maximumWidth); - usedImages.insert(newInfo.m_imageName); - } - } - - // Clear unused images. - for (auto it = m_images.begin(); it != m_images.end();) { - if (!usedImages.contains(it.key())) { - // Remove the image. - it = m_images.erase(it); - } else { - ++it; - } - } - - qDebug() << "updateBlockInfos() blocks" << m_blocksInfo.size() - << "images" << m_images.size(); -} - -const VBlockImageInfo *VImageResourceManager::findImageInfoByBlock(int p_blockNumber) const -{ - auto it = m_blocksInfo.find(p_blockNumber); - if (it != m_blocksInfo.end()) { - return &it.value(); - } - - return NULL; -} - -const QPixmap *VImageResourceManager::findImage(const QString &p_name) const -{ - auto it = m_images.find(p_name); - if (it != m_images.end()) { - return &it.value(); - } - - return NULL; -} - -void VImageResourceManager::clear() -{ - m_blocksInfo.clear(); - m_images.clear(); -} - -void VImageResourceManager::updateImageWidth(int p_maximumWidth) -{ - qDebug() << "updateImageWidth()" << p_maximumWidth; - m_maximumImageWidth = 0; - for (auto it = m_blocksInfo.begin(); it != m_blocksInfo.end(); ++it) { - VBlockImageInfo &info = it.value(); - auto imageIt = m_images.find(info.m_imageName); - if (imageIt != m_images.end()) { - info.m_imageWidth = imageIt.value().width(); - info.m_imageHeight = imageIt.value().height(); - adjustWidthAndHeight(info, p_maximumWidth); - updateMaximumImageWidth(info, p_maximumWidth); - } - } -} - -void VImageResourceManager::adjustWidthAndHeight(VBlockImageInfo &p_info, - int p_maximumWidth) -{ - int oriWidth = p_info.m_imageWidth; - int availableWidth = p_maximumWidth - p_info.m_margin; - if (availableWidth < p_info.m_imageWidth) { - if (availableWidth >= VPlainTextEdit::c_minimumImageWidth) { - p_info.m_imageWidth = availableWidth; - } else { - // Omit the margin when displaying this image. - p_info.m_imageWidth = p_maximumWidth; - } - } - - if (oriWidth != p_info.m_imageWidth) { - // Update the height respecting the ratio. - p_info.m_imageHeight = (1.0 * p_info.m_imageWidth / oriWidth) * p_info.m_imageHeight; - } -} - -void VImageResourceManager::updateMaximumImageWidth(const VBlockImageInfo &p_info, - int p_maximumWidth) -{ - int width = p_info.m_imageWidth + p_info.m_margin; - if (width > p_maximumWidth) { - width = p_info.m_imageWidth; - } - - if (width > m_maximumImageWidth) { - m_maximumImageWidth = width; - } -} diff --git a/src/vimageresourcemanager.h b/src/vimageresourcemanager.h deleted file mode 100644 index 517e7717..00000000 --- a/src/vimageresourcemanager.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef VIMAGERESOURCEMANAGER_H -#define VIMAGERESOURCEMANAGER_H - -#include -#include -#include -#include -#include - -struct VBlockImageInfo; - - -class VImageResourceManager -{ -public: - VImageResourceManager(); - - // Add an image to the resource with @p_name as the key. - // If @p_name already exists in the resources, it will update it. - void addImage(const QString &p_name, const QPixmap &p_image); - - // Whether the resources contains image with name @p_name. - bool contains(const QString &p_name) const; - - // Update the block-image info for all blocks. - // @p_maximumWidth: maximum width of the images plus the margin. - void updateBlockInfos(const QVector &p_blocksInfo, - int p_maximumWidth = INT_MAX); - - const VBlockImageInfo *findImageInfoByBlock(int p_blockNumber) const; - - const QPixmap *findImage(const QString &p_name) const; - - void clear(); - - // Update the width of all the block info. - void updateImageWidth(int p_maximumWidth); - - // Get the maximum width of all block images. - int getMaximumImageWidth() const; - -private: - // Adjust the width and height according to @p_maximumWidth and margin. - void adjustWidthAndHeight(VBlockImageInfo &p_info, int p_maximumWidth); - - void updateMaximumImageWidth(const VBlockImageInfo &p_info, int p_maximumWidth); - - // All the images resources. - QHash m_images; - - // Image info of all the blocks with image. - QHash m_blocksInfo; - - // Maximum width of all images from m_blocksInfo. - int m_maximumImageWidth; -}; - -inline int VImageResourceManager::getMaximumImageWidth() const -{ - return m_maximumImageWidth; -} - -#endif // VIMAGERESOURCEMANAGER_H diff --git a/src/vimageresourcemanager2.cpp b/src/vimageresourcemanager2.cpp deleted file mode 100644 index 45e97ff7..00000000 --- a/src/vimageresourcemanager2.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "vimageresourcemanager2.h" - - -VImageResourceManager2::VImageResourceManager2() -{ -} - -void VImageResourceManager2::addImage(const QString &p_name, - const QPixmap &p_image) -{ - m_images.insert(p_name, p_image); -} - -bool VImageResourceManager2::contains(const QString &p_name) const -{ - return m_images.contains(p_name); -} - -const QPixmap *VImageResourceManager2::findImage(const QString &p_name) const -{ - auto it = m_images.find(p_name); - if (it != m_images.end()) { - return &it.value(); - } - - return NULL; -} - -void VImageResourceManager2::clear() -{ - m_images.clear(); -} - -void VImageResourceManager2::removeImage(const QString &p_name) -{ - m_images.remove(p_name); -} diff --git a/src/vimageresourcemanager2.h b/src/vimageresourcemanager2.h deleted file mode 100644 index 61407a96..00000000 --- a/src/vimageresourcemanager2.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef VIMAGERESOURCEMANAGER2_H -#define VIMAGERESOURCEMANAGER2_H - -#include -#include -#include - - -class VImageResourceManager2 -{ -public: - VImageResourceManager2(); - - // Add an image to the resource with @p_name as the key. - // If @p_name already exists in the resources, it will update it. - void addImage(const QString &p_name, const QPixmap &p_image); - - // Remove image @p_name. - void removeImage(const QString &p_name); - - // Whether the resources contains image with name @p_name. - bool contains(const QString &p_name) const; - - const QPixmap *findImage(const QString &p_name) const; - - void clear(); - -private: - // All the images resources. - QHash m_images; -}; - -#endif // VIMAGERESOURCEMANAGER2_H diff --git a/src/vinsertselector.cpp b/src/vinsertselector.cpp deleted file mode 100644 index 53860bf1..00000000 --- a/src/vinsertselector.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#include "vinsertselector.h" - -#include -#include "utils/vutils.h" - -VSelectorItemWidget::VSelectorItemWidget(QWidget *p_parent) - : QWidget(p_parent) -{ -} - -VSelectorItemWidget::VSelectorItemWidget(const VInsertSelectorItem &p_item, QWidget *p_parent) - : QWidget(p_parent), m_name(p_item.m_name) -{ - QLabel *shortcutLabel = new QLabel(p_item.m_shortcut); - shortcutLabel->setProperty("SelectorItemShortcutLabel", true); - - m_btn = new QPushButton(p_item.m_name); - m_btn->setToolTip(p_item.m_toolTip); - m_btn->setProperty("SelectionBtn", true); - connect(m_btn, &QPushButton::clicked, - this, [this]() { - emit clicked(m_name); - }); - - QHBoxLayout *layout = new QHBoxLayout(); - layout->addWidget(shortcutLabel); - layout->addWidget(m_btn, 1); - layout->setContentsMargins(0, 0, 0, 0); - - setLayout(layout); -} - -VInsertSelector::VInsertSelector(int p_nrRows, - const QVector &p_items, - QWidget *p_parent) - : QWidget(p_parent), - m_items(p_items) -{ - setupUI(p_nrRows < 1 ? 1 : p_nrRows); -} - -void VInsertSelector::setupUI(int p_nrRows) -{ - QGridLayout *layout = new QGridLayout(); - - int row = 0, col = 0; - for (auto const & it : m_items) { - QWidget *wid = createItemWidget(it); - layout->addWidget(wid, row, col); - if (++row == p_nrRows) { - row = 0; - ++col; - } - } - - setLayout(layout); -} - -QWidget *VInsertSelector::createItemWidget(const VInsertSelectorItem &p_item) -{ - VSelectorItemWidget *widget = new VSelectorItemWidget(p_item); - connect(widget, &VSelectorItemWidget::clicked, - this, &VInsertSelector::itemClicked); - - return widget; -} - -void VInsertSelector::itemClicked(const QString &p_name) -{ - m_clickedItemName = p_name; - emit accepted(true); -} - -void VInsertSelector::keyPressEvent(QKeyEvent *p_event) -{ - QWidget::keyPressEvent(p_event); - - if (p_event->key() == Qt::Key_BracketLeft - && VUtils::isControlModifierForVim(p_event->modifiers())) { - m_clickedItemName.clear(); - emit accepted(false); - return; - } - - QChar ch = VUtils::keyToChar(p_event->key()); - if (!ch.isNull()) { - // Activate corresponding item. - const VInsertSelectorItem *item = findItemByShortcut(ch); - if (item) { - itemClicked(item->m_name); - } - } -} - -const VInsertSelectorItem *VInsertSelector::findItemByShortcut(QChar p_shortcut) const -{ - for (auto const & it : m_items) { - if (it.m_shortcut == p_shortcut) { - return ⁢ - } - } - - return NULL; -} - -void VInsertSelector::showEvent(QShowEvent *p_event) -{ - QWidget::showEvent(p_event); - - if (!hasFocus()) { - setFocus(); - } -} - -void VInsertSelector::paintEvent(QPaintEvent *p_event) -{ - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); - - QWidget::paintEvent(p_event); -} diff --git a/src/vinsertselector.h b/src/vinsertselector.h deleted file mode 100644 index ee04fa36..00000000 --- a/src/vinsertselector.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef VINSERTSELECTOR_H -#define VINSERTSELECTOR_H - -#include -#include - -class QPushButton; -class QKeyEvent; -class QShowEvent; -class QPaintEvent; - -struct VInsertSelectorItem -{ - VInsertSelectorItem() - { - } - - VInsertSelectorItem(const QString &p_name, - const QString &p_toolTip, - QChar p_shortcut = QChar()) - : m_name(p_name), m_toolTip(p_toolTip), m_shortcut(p_shortcut) - { - } - - QString m_name; - - QString m_toolTip; - - QChar m_shortcut; -}; - -class VSelectorItemWidget : public QWidget -{ - Q_OBJECT -public: - explicit VSelectorItemWidget(QWidget *p_parent = nullptr); - - VSelectorItemWidget(const VInsertSelectorItem &p_item, QWidget *p_parent = nullptr); - -signals: - // This item widget is clicked. - void clicked(const QString &p_name); - -private: - QString m_name; - - QPushButton *m_btn; -}; - -class VInsertSelector : public QWidget -{ - Q_OBJECT -public: - explicit VInsertSelector(int p_nrRows, - const QVector &p_items, - QWidget *p_parent = nullptr); - - const QString &getClickedItem() const; - -signals: - void accepted(bool p_accepted = true); - -protected: - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - - void paintEvent(QPaintEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - void itemClicked(const QString &p_name); - -private: - void setupUI(int p_nrRows); - - QWidget *createItemWidget(const VInsertSelectorItem &p_item); - - const VInsertSelectorItem *findItemByShortcut(QChar p_shortcut) const; - - QVector m_items; - - QString m_clickedItemName; -}; - -inline const QString &VInsertSelector::getClickedItem() const -{ - return m_clickedItemName; -} - -#endif // VINSERTSELECTOR_H diff --git a/src/vlineedit.cpp b/src/vlineedit.cpp deleted file mode 100644 index e7b65368..00000000 --- a/src/vlineedit.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "vlineedit.h" - -#include -#include - -#include "utils/vmetawordmanager.h" - -extern VMetaWordManager *g_mwMgr; - - -VLineEdit::VLineEdit(QWidget *p_parent) - : QLineEdit(p_parent) -{ - init(); -} - -VLineEdit::VLineEdit(const QString &p_contents, QWidget *p_parent) - : QLineEdit(p_contents, p_parent) -{ - init(); -} - -void VLineEdit::handleTextChanged(const QString &p_text) -{ - m_evaluatedText = g_mwMgr->evaluate(p_text); - qDebug() << "evaluate text:" << m_evaluatedText; - - if (m_evaluatedText == p_text) { - return; - } - - // Display tooltip at bottom-left. - QPoint pos = mapToGlobal(QPoint(0, height())); - QToolTip::showText(pos, m_evaluatedText, this); -} - -void VLineEdit::init() -{ - m_evaluatedText = g_mwMgr->evaluate(text()); - - connect(this, &QLineEdit::textChanged, - this, &VLineEdit::handleTextChanged); -} - -const QString &VLineEdit::getEvaluatedText() const -{ - return m_evaluatedText; -} diff --git a/src/vlineedit.h b/src/vlineedit.h deleted file mode 100644 index 67934f9e..00000000 --- a/src/vlineedit.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef VLINEEDIT_H -#define VLINEEDIT_H - -#include - - -// QLineEdit with meta word support. -class VLineEdit : public QLineEdit -{ - Q_OBJECT -public: - explicit VLineEdit(QWidget *p_parent = nullptr); - - VLineEdit(const QString &p_contents, QWidget *p_parent = Q_NULLPTR); - - // Return the evaluated text. - const QString &getEvaluatedText() const; - -private slots: - void handleTextChanged(const QString &p_text); - -private: - void init(); - - // We should keep the evaluated text identical with what's displayed. - QString m_evaluatedText; -}; - -#endif // VLINEEDIT_H diff --git a/src/vlinenumberarea.cpp b/src/vlinenumberarea.cpp deleted file mode 100644 index 5a91b445..00000000 --- a/src/vlinenumberarea.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "vlinenumberarea.h" - -#include -#include - -VLineNumberArea::VLineNumberArea(VTextEditWithLineNumber *p_editor, - const QTextDocument *p_document, - int p_digitWidth, - int p_digitHeight, - QWidget *p_parent) - : QWidget(p_parent), - m_editor(p_editor), - m_document(p_document), - m_width(0), - m_blockCount(-1), - m_digitWidth(p_digitWidth), - m_digitHeight(p_digitHeight), - m_foregroundColor("black"), - m_backgroundColor("grey") -{ -} - -int VLineNumberArea::calculateWidth() const -{ - int bc = m_document->blockCount(); - if (m_blockCount == bc) { - return m_width; - } - - const_cast(this)->m_blockCount = bc; - int digits = 1; - int max = qMax(1, m_blockCount); - while (max >= 10) { - max /= 10; - ++digits; - } - - int width = m_digitWidth * (digits + 1); - const_cast(this)->m_width = width; - - return m_width; -} diff --git a/src/vlinenumberarea.h b/src/vlinenumberarea.h deleted file mode 100644 index 014151b4..00000000 --- a/src/vlinenumberarea.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef VLINENUMBERAREA_H -#define VLINENUMBERAREA_H - -#include -#include - -class QPaintEvent; -class QTextDocument; - - -enum class LineNumberType -{ - None = 0, - Absolute, - Relative, - CodeBlock, - Invalid -}; - - -class VTextEditWithLineNumber -{ -public: - virtual ~VTextEditWithLineNumber() {} - - virtual void paintLineNumberArea(QPaintEvent *p_event) = 0; -}; - - -// To use VLineNumberArea, the editor should implement VTextEditWithLineNumber. -class VLineNumberArea : public QWidget -{ - Q_OBJECT -public: - VLineNumberArea(VTextEditWithLineNumber *p_editor, - const QTextDocument *p_document, - int p_digitWidth, - int p_digitHeight, - QWidget *p_parent = nullptr); - - QSize sizeHint() const Q_DECL_OVERRIDE - { - return QSize(calculateWidth(), 0); - } - - int calculateWidth() const; - - int getDigitHeight() const - { - return m_digitHeight; - } - - const QColor &getBackgroundColor() const; - void setBackgroundColor(const QColor &p_color); - - const QColor &getForegroundColor() const; - void setForegroundColor(const QColor &p_color); - -protected: - void paintEvent(QPaintEvent *p_event) Q_DECL_OVERRIDE - { - m_editor->paintLineNumberArea(p_event); - } - -private: - VTextEditWithLineNumber *m_editor; - const QTextDocument *m_document; - int m_width; - int m_blockCount; - int m_digitWidth; - int m_digitHeight; - QColor m_foregroundColor; - QColor m_backgroundColor; -}; - -inline const QColor &VLineNumberArea::getBackgroundColor() const -{ - return m_backgroundColor; -} - -inline void VLineNumberArea::setBackgroundColor(const QColor &p_color) -{ - m_backgroundColor = p_color; -} - -inline const QColor &VLineNumberArea::getForegroundColor() const -{ - return m_foregroundColor; -} - -inline void VLineNumberArea::setForegroundColor(const QColor &p_color) -{ - m_foregroundColor = p_color; -} - -#endif // VLINENUMBERAREA_H diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp deleted file mode 100644 index 72a667ee..00000000 --- a/src/vmainwindow.cpp +++ /dev/null @@ -1,2746 +0,0 @@ -#include -#include -#include -#include -#include -#include "vmainwindow.h" -#include "vdirectorytree.h" -#include "vnote.h" -#include "vfilelist.h" -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "veditarea.h" -#include "voutline.h" -#include "vnotebookselector.h" -#include "vavatar.h" -#include "dialog/vfindreplacedialog.h" -#include "dialog/vsettingsdialog.h" -#include "vcaptain.h" -#include "vedittab.h" -#include "vwebview.h" -#include "vexporter.h" -#include "vmdtab.h" -#include "vvimindicator.h" -#include "vtabindicator.h" -#include "dialog/vupdater.h" -#include "vorphanfile.h" -#include "dialog/vorphanfileinfodialog.h" -#include "vsingleinstanceguard.h" -#include "vnotefile.h" -#include "vbuttonwithwidget.h" -#include "vattachmentlist.h" -#include "vfilesessioninfo.h" -#include "vsnippetlist.h" -#include "vtoolbox.h" -#include "vbuttonmenuitem.h" -#include "vpalette.h" -#include "utils/viconutils.h" - -VMainWindow *g_mainWin; - -extern VConfigManager *g_config; - -extern VPalette *g_palette; - -VNote *g_vnote; - -const int VMainWindow::c_sharedMemTimerInterval = 1000; - -#if defined(QT_NO_DEBUG) -extern QFile g_logFile; -#endif - - -VMainWindow::VMainWindow(VSingleInstanceGuard *p_guard, QWidget *p_parent) - : QMainWindow(p_parent), m_guard(p_guard), - m_windowOldState(Qt::WindowNoState), m_requestQuit(false) -{ - qsrand(QDateTime::currentDateTime().toTime_t()); - - g_mainWin = this; - - setWindowIcon(QIcon(":/resources/icons/vnote.ico")); - vnote = new VNote(this); - g_vnote = vnote; - initPredefinedColorPixmaps(); - - if (g_config->getEnableCompactMode()) { - m_panelViewState = PanelViewState::CompactMode; - } else { - m_panelViewState = PanelViewState::TwoPanels; - } - - initCaptain(); - - setupUI(); - - initMenuBar(); - - initToolBar(); - - initShortcuts(); - - initDockWindows(); - - initAvatar(); - - changePanelView(m_panelViewState); - - restoreStateAndGeometry(); - - setContextMenuPolicy(Qt::NoContextMenu); - - notebookSelector->update(); - - initSharedMemoryWatcher(); - - registerCaptainAndNavigationTargets(); -} - -void VMainWindow::initSharedMemoryWatcher() -{ - m_sharedMemTimer = new QTimer(this); - m_sharedMemTimer->setSingleShot(false); - m_sharedMemTimer->setInterval(c_sharedMemTimerInterval); - connect(m_sharedMemTimer, &QTimer::timeout, - this, &VMainWindow::checkSharedMemory); - - m_sharedMemTimer->start(); -} - -void VMainWindow::initCaptain() -{ - // VCaptain should be visible to accpet key focus. But VCaptain - // may hide other widgets. - m_captain = new VCaptain(this); - connect(m_captain, &VCaptain::captainModeChanged, - this, [this](bool p_captainMode) { - static QString normalBaseColor = m_avatar->getBaseColor(); - static QString captainModeColor = g_palette->color("avatar_captain_mode_border_bg"); - - if (p_captainMode) { - m_avatar->updateBaseColor(captainModeColor); - } else { - m_avatar->updateBaseColor(normalBaseColor); - } - }); -} - -void VMainWindow::registerCaptainAndNavigationTargets() -{ - m_captain->registerNavigationTarget(notebookSelector); - m_captain->registerNavigationTarget(directoryTree); - m_captain->registerNavigationTarget(m_fileList); - m_captain->registerNavigationTarget(editArea); - m_captain->registerNavigationTarget(m_toolBox); - m_captain->registerNavigationTarget(outline); - m_captain->registerNavigationTarget(m_snippetList); - - // Register Captain mode targets. - m_captain->registerCaptainTarget(tr("AttachmentList"), - g_config->getCaptainShortcutKeySequence("AttachmentList"), - this, - showAttachmentListByCaptain); - m_captain->registerCaptainTarget(tr("LocateCurrentFile"), - g_config->getCaptainShortcutKeySequence("LocateCurrentFile"), - this, - locateCurrentFileByCaptain); - m_captain->registerCaptainTarget(tr("ExpandMode"), - g_config->getCaptainShortcutKeySequence("ExpandMode"), - this, - toggleExpandModeByCaptain); - m_captain->registerCaptainTarget(tr("OnePanelView"), - g_config->getCaptainShortcutKeySequence("OnePanelView"), - this, - toggleOnePanelViewByCaptain); - m_captain->registerCaptainTarget(tr("DiscardAndRead"), - g_config->getCaptainShortcutKeySequence("DiscardAndRead"), - this, - discardAndReadByCaptain); - m_captain->registerCaptainTarget(tr("ToolsDock"), - g_config->getCaptainShortcutKeySequence("ToolsDock"), - this, - toggleToolsDockByCaptain); - m_captain->registerCaptainTarget(tr("CloseNote"), - g_config->getCaptainShortcutKeySequence("CloseNote"), - this, - closeFileByCaptain); - m_captain->registerCaptainTarget(tr("ShortcutsHelp"), - g_config->getCaptainShortcutKeySequence("ShortcutsHelp"), - this, - shortcutsHelpByCaptain); - m_captain->registerCaptainTarget(tr("FlushLogFile"), - g_config->getCaptainShortcutKeySequence("FlushLogFile"), - this, - flushLogFileByCaptain); -} - -void VMainWindow::setupUI() -{ - QWidget *directoryPanel = setupDirectoryPanel(); - - m_fileList = new VFileList(); - m_fileList->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); - - editArea = new VEditArea(); - editArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - m_findReplaceDialog = editArea->getFindReplaceDialog(); - m_fileList->setEditArea(editArea); - directoryTree->setEditArea(editArea); - - // Main Splitter - m_mainSplitter = new QSplitter(); - m_mainSplitter->setObjectName("MainSplitter"); - m_mainSplitter->addWidget(directoryPanel); - m_mainSplitter->addWidget(m_fileList); - setTabOrder(directoryTree, m_fileList->getContentWidget()); - m_mainSplitter->addWidget(editArea); - m_mainSplitter->setStretchFactor(0, 0); - m_mainSplitter->setStretchFactor(1, 0); - m_mainSplitter->setStretchFactor(2, 1); - - // Signals - connect(directoryTree, &VDirectoryTree::currentDirectoryChanged, - m_fileList, &VFileList::setDirectory); - connect(directoryTree, &VDirectoryTree::directoryUpdated, - editArea, &VEditArea::handleDirectoryUpdated); - - connect(notebookSelector, &VNotebookSelector::notebookUpdated, - editArea, &VEditArea::handleNotebookUpdated); - connect(notebookSelector, &VNotebookSelector::notebookCreated, - directoryTree, [this](const QString &p_name, bool p_import) { - Q_UNUSED(p_name); - if (!p_import) { - directoryTree->newRootDirectory(); - } - }); - - connect(m_fileList, &VFileList::fileClicked, - editArea, &VEditArea::openFile); - connect(m_fileList, &VFileList::fileCreated, - editArea, &VEditArea::openFile); - connect(m_fileList, &VFileList::fileUpdated, - editArea, &VEditArea::handleFileUpdated); - connect(editArea, &VEditArea::tabStatusUpdated, - this, &VMainWindow::handleAreaTabStatusUpdated); - connect(editArea, &VEditArea::statusMessage, - this, &VMainWindow::showStatusMessage); - connect(editArea, &VEditArea::vimStatusUpdated, - this, &VMainWindow::handleVimStatusUpdated); - connect(m_findReplaceDialog, &VFindReplaceDialog::findTextChanged, - this, &VMainWindow::handleFindDialogTextChanged); - - setCentralWidget(m_mainSplitter); - - m_vimIndicator = new VVimIndicator(this); - m_vimIndicator->hide(); - - m_tabIndicator = new VTabIndicator(this); - m_tabIndicator->hide(); - - // Create and show the status bar - statusBar()->addPermanentWidget(m_vimIndicator); - statusBar()->addPermanentWidget(m_tabIndicator); - - initTrayIcon(); -} - -QWidget *VMainWindow::setupDirectoryPanel() -{ - // Notebook selector. - notebookLabel = new QLabel(tr("Notebooks")); - notebookLabel->setProperty("TitleLabel", true); - notebookLabel->setProperty("NotebookPanel", true); - - notebookSelector = new VNotebookSelector(); - notebookSelector->setObjectName("NotebookSelector"); - notebookSelector->setProperty("NotebookPanel", true); - notebookSelector->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); - - // Navigation panel. - directoryLabel = new QLabel(tr("Folders")); - directoryLabel->setProperty("TitleLabel", true); - directoryLabel->setProperty("NotebookPanel", true); - - directoryTree = new VDirectoryTree; - directoryTree->setProperty("NotebookPanel", true); - - QVBoxLayout *naviLayout = new QVBoxLayout; - naviLayout->addWidget(directoryLabel); - naviLayout->addWidget(directoryTree); - naviLayout->setContentsMargins(0, 0, 0, 0); - naviLayout->setSpacing(0); - QWidget *naviWidget = new QWidget(); - naviWidget->setLayout(naviLayout); - - QWidget *tmpWidget = new QWidget(); - - // Compact splitter. - m_naviSplitter = new QSplitter(); - m_naviSplitter->setOrientation(Qt::Vertical); - m_naviSplitter->setObjectName("NaviSplitter"); - m_naviSplitter->addWidget(naviWidget); - m_naviSplitter->addWidget(tmpWidget); - m_naviSplitter->setStretchFactor(0, 0); - m_naviSplitter->setStretchFactor(1, 1); - - tmpWidget->hide(); - - QVBoxLayout *nbLayout = new QVBoxLayout; - nbLayout->addWidget(notebookLabel); - nbLayout->addWidget(notebookSelector); - nbLayout->addWidget(m_naviSplitter); - nbLayout->setContentsMargins(0, 0, 0, 0); - nbLayout->setSpacing(0); - QWidget *nbContainer = new QWidget(); - nbContainer->setObjectName("NotebookPanel"); - nbContainer->setLayout(nbLayout); - nbContainer->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); - - connect(notebookSelector, &VNotebookSelector::curNotebookChanged, - this, [this](VNotebook *p_notebook) { - directoryTree->setNotebook(p_notebook); - directoryTree->setFocus(); - }); - - connect(notebookSelector, &VNotebookSelector::curNotebookChanged, - this, &VMainWindow::handleCurrentNotebookChanged); - - connect(directoryTree, &VDirectoryTree::currentDirectoryChanged, - this, &VMainWindow::handleCurrentDirectoryChanged); - - return nbContainer; -} - -void VMainWindow::initToolBar() -{ - const int tbIconSize = g_config->getToolBarIconSize() * VUtils::calculateScaleFactor(); - QSize iconSize(tbIconSize, tbIconSize); - - initFileToolBar(iconSize); - initViewToolBar(iconSize); - initEditToolBar(iconSize); - initNoteToolBar(iconSize); -} - -void VMainWindow::initViewToolBar(QSize p_iconSize) -{ - QToolBar *viewToolBar = addToolBar(tr("View")); - viewToolBar->setObjectName("ViewToolBar"); - viewToolBar->setMovable(false); - if (p_iconSize.isValid()) { - viewToolBar->setIconSize(p_iconSize); - } - - m_viewActGroup = new QActionGroup(this); - QAction *onePanelViewAct = new QAction(VIconUtils::menuIcon(":/resources/icons/one_panel.svg"), - tr("&Single Panel"), - m_viewActGroup); - onePanelViewAct->setStatusTip(tr("Display only the notes list panel")); - onePanelViewAct->setToolTip(tr("Single Panel")); - onePanelViewAct->setCheckable(true); - onePanelViewAct->setData((int)PanelViewState::SinglePanel); - - QAction *twoPanelViewAct = new QAction(VIconUtils::menuIcon(":/resources/icons/two_panels.svg"), - tr("&Two Panels"), - m_viewActGroup); - twoPanelViewAct->setStatusTip(tr("Display both the folders and notes list panel")); - twoPanelViewAct->setToolTip(tr("Two Panels")); - twoPanelViewAct->setCheckable(true); - twoPanelViewAct->setData((int)PanelViewState::TwoPanels); - - QAction *compactViewAct = new QAction(VIconUtils::menuIcon(":/resources/icons/compact_mode.svg"), - tr("&Compact Mode"), - m_viewActGroup); - compactViewAct->setStatusTip(tr("Integrate the folders and notes list panel in one column")); - compactViewAct->setCheckable(true); - compactViewAct->setData((int)PanelViewState::CompactMode); - - connect(m_viewActGroup, &QActionGroup::triggered, - this, [this](QAction *p_action) { - if (!p_action) { - return; - } - - int act = p_action->data().toInt(); - switch (act) { - case (int)PanelViewState::SinglePanel: - onePanelView(); - break; - - case (int)PanelViewState::TwoPanels: - twoPanelView(); - break; - - case (int)PanelViewState::CompactMode: - compactModeView(); - break; - - default: - break; - } - }); - - QMenu *panelMenu = new QMenu(this); - panelMenu->setToolTipsVisible(true); - panelMenu->addAction(onePanelViewAct); - panelMenu->addAction(twoPanelViewAct); - panelMenu->addAction(compactViewAct); - - expandViewAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/expand.svg"), - tr("Expand"), this); - expandViewAct->setStatusTip(tr("Expand the edit area")); - expandViewAct->setCheckable(true); - expandViewAct->setMenu(panelMenu); - connect(expandViewAct, &QAction::triggered, - this, [this](bool p_checked) { - // Recover m_panelViewState or change to expand mode. - changePanelView(p_checked ? PanelViewState::ExpandMode - : m_panelViewState); - }); - - viewToolBar->addAction(expandViewAct); -} - -// Enable/disable all actions of @p_widget. -static void setActionsEnabled(QWidget *p_widget, bool p_enabled) -{ - Q_ASSERT(p_widget); - QList actions = p_widget->actions(); - for (auto const & act : actions) { - act->setEnabled(p_enabled); - } -} - -void VMainWindow::initEditToolBar(QSize p_iconSize) -{ - m_editToolBar = addToolBar(tr("Edit Toolbar")); - m_editToolBar->setObjectName("EditToolBar"); - m_editToolBar->setMovable(false); - if (p_iconSize.isValid()) { - m_editToolBar->setIconSize(p_iconSize); - } - - m_editToolBar->addSeparator(); - - m_headingSequenceAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/heading_sequence.svg"), - tr("Heading Sequence"), - this); - m_headingSequenceAct->setStatusTip(tr("Enable heading sequence in current note in edit mode")); - m_headingSequenceAct->setCheckable(true); - connect(m_headingSequenceAct, &QAction::triggered, - this, [this](bool p_checked){ - if (isHeadingSequenceApplicable()) { - VMdTab *tab = dynamic_cast(m_curTab.data()); - Q_ASSERT(tab); - tab->enableHeadingSequence(p_checked); - } - }); - - m_editToolBar->addAction(m_headingSequenceAct); - - initHeadingButton(m_editToolBar); - - QAction *boldAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/bold.svg"), - tr("Bold\t%1").arg(VUtils::getShortcutText("Ctrl+B")), - this); - boldAct->setStatusTip(tr("Insert bold text or change selected text to bold")); - connect(boldAct, &QAction::triggered, - this, [this](){ - if (m_curTab) { - m_curTab->decorateText(TextDecoration::Bold); - } - }); - - m_editToolBar->addAction(boldAct); - - QAction *italicAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/italic.svg"), - tr("Italic\t%1").arg(VUtils::getShortcutText("Ctrl+I")), - this); - italicAct->setStatusTip(tr("Insert italic text or change selected text to italic")); - connect(italicAct, &QAction::triggered, - this, [this](){ - if (m_curTab) { - m_curTab->decorateText(TextDecoration::Italic); - } - }); - - m_editToolBar->addAction(italicAct); - - QAction *strikethroughAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/strikethrough.svg"), - tr("Strikethrough\t%1").arg(VUtils::getShortcutText("Ctrl+D")), - this); - strikethroughAct->setStatusTip(tr("Insert strikethrough text or change selected text to strikethroughed")); - connect(strikethroughAct, &QAction::triggered, - this, [this](){ - if (m_curTab) { - m_curTab->decorateText(TextDecoration::Strikethrough); - } - }); - - m_editToolBar->addAction(strikethroughAct); - - QAction *inlineCodeAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/inline_code.svg"), - tr("Inline Code\t%1").arg(VUtils::getShortcutText("Ctrl+K")), - this); - inlineCodeAct->setStatusTip(tr("Insert inline-code text or change selected text to inline-coded")); - connect(inlineCodeAct, &QAction::triggered, - this, [this](){ - if (m_curTab) { - m_curTab->decorateText(TextDecoration::InlineCode); - } - }); - - m_editToolBar->addAction(inlineCodeAct); - - QAction *codeBlockAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/code_block.svg"), - tr("Code Block\t%1").arg(VUtils::getShortcutText("Ctrl+M")), - this); - codeBlockAct->setStatusTip(tr("Insert fenced code block text or wrap selected text into a fenced code block")); - connect(codeBlockAct, &QAction::triggered, - this, [this](){ - if (m_curTab) { - m_curTab->decorateText(TextDecoration::CodeBlock); - } - }); - - m_editToolBar->addAction(codeBlockAct); - - // Insert link. - QAction *insetLinkAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/link.svg"), - tr("Insert Link\t%1").arg(VUtils::getShortcutText("Ctrl+L")), - this); - insetLinkAct->setStatusTip(tr("Insert a link")); - connect(insetLinkAct, &QAction::triggered, - this, [this]() { - if (m_curTab) { - m_curTab->insertLink(); - } - }); - - m_editToolBar->addAction(insetLinkAct); - - // Insert image. - QAction *insertImageAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/insert_image.svg"), - tr("Insert Image\t%1").arg(VUtils::getShortcutText("Ctrl+'")), - this); - insertImageAct->setStatusTip(tr("Insert an image from file or URL")); - connect(insertImageAct, &QAction::triggered, - this, [this]() { - if (m_curTab) { - m_curTab->insertImage(); - } - }); - - m_editToolBar->addAction(insertImageAct); - - QAction *toggleAct = m_editToolBar->toggleViewAction(); - toggleAct->setToolTip(tr("Toggle the edit toolbar")); - viewMenu->addAction(toggleAct); - - setActionsEnabled(m_editToolBar, false); -} - -void VMainWindow::initNoteToolBar(QSize p_iconSize) -{ - QToolBar *noteToolBar = addToolBar(tr("Note Toolbar")); - noteToolBar->setObjectName("NoteToolBar"); - noteToolBar->setMovable(false); - if (p_iconSize.isValid()) { - noteToolBar->setIconSize(p_iconSize); - } - - noteToolBar->addSeparator(); - - // Attachment. - m_attachmentList = new VAttachmentList(this); - m_attachmentBtn = new VButtonWithWidget(VIconUtils::toolButtonIcon(":/resources/icons/attachment.svg"), - "", - m_attachmentList, - this); - m_attachmentBtn->setBubbleColor(g_palette->color("bubble_fg"), - g_palette->color("bubble_bg")); - m_attachmentBtn->setToolTip(tr("Attachments (drag files here to add attachments)")); - m_attachmentBtn->setProperty("CornerBtn", true); - m_attachmentBtn->setFocusPolicy(Qt::NoFocus); - m_attachmentBtn->setEnabled(false); - - QAction *flashPageAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/flash_page.svg"), - tr("Flash Page"), - this); - flashPageAct->setStatusTip(tr("Open the Flash Page to edit")); - QString keySeq = g_config->getShortcutKeySequence("FlashPage"); - qDebug() << "set FlashPage shortcut to" << keySeq; - flashPageAct->setShortcut(QKeySequence(keySeq)); - connect(flashPageAct, &QAction::triggered, - this, &VMainWindow::openFlashPage); - - noteToolBar->addWidget(m_attachmentBtn); - noteToolBar->addAction(flashPageAct); -} - -void VMainWindow::initFileToolBar(QSize p_iconSize) -{ - QToolBar *fileToolBar = addToolBar(tr("Note")); - fileToolBar->setObjectName("NoteToolBar"); - fileToolBar->setMovable(false); - if (p_iconSize.isValid()) { - fileToolBar->setIconSize(p_iconSize); - } - - newRootDirAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/create_rootdir_tb.svg"), - tr("New &Root Folder"), - this); - newRootDirAct->setStatusTip(tr("Create a root folder in current notebook")); - connect(newRootDirAct, &QAction::triggered, - directoryTree, &VDirectoryTree::newRootDirectory); - - newNoteAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/create_note_tb.svg"), - tr("New &Note"), this); - newNoteAct->setStatusTip(tr("Create a note in current folder")); - QString keySeq = g_config->getShortcutKeySequence("NewNote"); - qDebug() << "set NewNote shortcut to" << keySeq; - newNoteAct->setShortcut(QKeySequence(keySeq)); - connect(newNoteAct, &QAction::triggered, - m_fileList, &VFileList::newFile); - - noteInfoAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/note_info_tb.svg"), - tr("Note &Info"), this); - noteInfoAct->setStatusTip(tr("View and edit current note's information")); - connect(noteInfoAct, &QAction::triggered, - this, &VMainWindow::curEditFileInfo); - - deleteNoteAct = new QAction(VIconUtils::toolButtonDangerIcon(":/resources/icons/delete_note_tb.svg"), - tr("&Delete Note"), this); - deleteNoteAct->setStatusTip(tr("Delete current note")); - connect(deleteNoteAct, &QAction::triggered, - this, &VMainWindow::deleteCurNote); - - editNoteAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/edit_note.svg"), - tr("&Edit"), this); - editNoteAct->setStatusTip(tr("Edit current note")); - keySeq = g_config->getShortcutKeySequence("EditNote"); - qDebug() << "set EditNote shortcut to" << keySeq; - editNoteAct->setShortcut(QKeySequence(keySeq)); - connect(editNoteAct, &QAction::triggered, - editArea, &VEditArea::editFile); - - discardExitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/discard_exit.svg"), - tr("Discard Changes And Read"), this); - discardExitAct->setStatusTip(tr("Discard changes and exit edit mode")); - discardExitAct->setToolTip(tr("Discard Changes And Read")); - connect(discardExitAct, &QAction::triggered, - editArea, &VEditArea::readFile); - - QMenu *exitEditMenu = new QMenu(this); - exitEditMenu->setToolTipsVisible(true); - exitEditMenu->addAction(discardExitAct); - - saveExitAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/save_exit.svg"), - tr("Save Changes And Read"), this); - saveExitAct->setStatusTip(tr("Save changes and exit edit mode")); - saveExitAct->setMenu(exitEditMenu); - keySeq = g_config->getShortcutKeySequence("SaveAndRead"); - qDebug() << "set SaveAndRead shortcut to" << keySeq; - saveExitAct->setShortcut(QKeySequence(keySeq)); - connect(saveExitAct, &QAction::triggered, - editArea, &VEditArea::saveAndReadFile); - - saveNoteAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/save_note.svg"), - tr("Save"), this); - saveNoteAct->setStatusTip(tr("Save changes to current note")); - keySeq = g_config->getShortcutKeySequence("SaveNote"); - qDebug() << "set SaveNote shortcut to" << keySeq; - saveNoteAct->setShortcut(QKeySequence(keySeq)); - connect(saveNoteAct, &QAction::triggered, - editArea, &VEditArea::saveFile); - - newRootDirAct->setEnabled(false); - newNoteAct->setEnabled(false); - noteInfoAct->setEnabled(false); - deleteNoteAct->setEnabled(false); - editNoteAct->setEnabled(false); - saveExitAct->setVisible(false); - discardExitAct->setVisible(false); - saveNoteAct->setEnabled(false); - - fileToolBar->addAction(newRootDirAct); - fileToolBar->addAction(newNoteAct); - fileToolBar->addAction(noteInfoAct); - fileToolBar->addAction(deleteNoteAct); - fileToolBar->addAction(editNoteAct); - fileToolBar->addAction(saveExitAct); - fileToolBar->addAction(saveNoteAct); -} - -void VMainWindow::initMenuBar() -{ - initFileMenu(); - initEditMenu(); - initViewMenu(); - initMarkdownMenu(); - initHelpMenu(); -} - -void VMainWindow::initHelpMenu() -{ - QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->setToolTipsVisible(true); - -#if defined(QT_NO_DEBUG) - QAction *logAct = new QAction(tr("View &Log"), this); - logAct->setToolTip(tr("View VNote's debug log (%1)").arg(g_config->getLogFilePath())); - connect(logAct, &QAction::triggered, - this, [](){ - QUrl url = QUrl::fromLocalFile(g_config->getLogFilePath()); - QDesktopServices::openUrl(url); - }); -#endif - - QAction *shortcutAct = new QAction(tr("&Shortcuts Help"), this); - shortcutAct->setToolTip(tr("View information about shortcut keys")); - connect(shortcutAct, &QAction::triggered, - this, &VMainWindow::shortcutsHelp); - - QAction *mdGuideAct = new QAction(tr("&Markdown Guide"), this); - mdGuideAct->setToolTip(tr("A quick guide of Markdown syntax")); - connect(mdGuideAct, &QAction::triggered, - this, [this](){ - QString locale = VUtils::getLocale(); - QString docName = VNote::c_markdownGuideDocFile_en; - if (locale == "zh_CN") { - docName = VNote::c_markdownGuideDocFile_zh; - } - - VFile *file = vnote->getOrphanFile(docName, false, true); - editArea->openFile(file, OpenFileMode::Read); - }); - - QAction *wikiAct = new QAction(tr("&Wiki"), this); - wikiAct->setToolTip(tr("View VNote's wiki on Github")); - connect(wikiAct, &QAction::triggered, - this, [this]() { - QString url("https://github.com/tamlok/vnote/wiki"); - QDesktopServices::openUrl(url); - }); - - QAction *updateAct = new QAction(tr("Check For &Updates"), this); - updateAct->setToolTip(tr("Check for updates of VNote")); - connect(updateAct, &QAction::triggered, - this, [this](){ - VUpdater updater(this); - updater.exec(); - }); - - QAction *starAct = new QAction(tr("Star VNote on &Github"), this); - starAct->setToolTip(tr("Give a star to VNote on Github project")); - connect(starAct, &QAction::triggered, - this, [this]() { - QString url("https://github.com/tamlok/vnote"); - QDesktopServices::openUrl(url); - }); - - QAction *feedbackAct = new QAction(tr("&Feedback"), this); - feedbackAct->setToolTip(tr("Open an issue on Github")); - connect(feedbackAct, &QAction::triggered, - this, [this]() { - QString url("https://github.com/tamlok/vnote/issues"); - QDesktopServices::openUrl(url); - }); - - QAction *aboutAct = new QAction(tr("&About VNote"), this); - aboutAct->setToolTip(tr("View information about VNote")); - aboutAct->setMenuRole(QAction::AboutRole); - connect(aboutAct, &QAction::triggered, - this, &VMainWindow::aboutMessage); - - QAction *aboutQtAct = new QAction(tr("About &Qt"), this); - aboutQtAct->setToolTip(tr("View information about Qt")); - aboutQtAct->setMenuRole(QAction::AboutQtRole); - connect(aboutQtAct, &QAction::triggered, - qApp, &QApplication::aboutQt); - - helpMenu->addAction(shortcutAct); - helpMenu->addAction(mdGuideAct); - helpMenu->addAction(wikiAct); - helpMenu->addAction(updateAct); - helpMenu->addAction(starAct); - helpMenu->addAction(feedbackAct); - -#if defined(QT_NO_DEBUG) - helpMenu->addAction(logAct); -#endif - - helpMenu->addAction(aboutQtAct); - helpMenu->addAction(aboutAct); -} - -void VMainWindow::initMarkdownMenu() -{ - QMenu *markdownMenu = menuBar()->addMenu(tr("&Markdown")); - markdownMenu->setToolTipsVisible(true); - - initConverterMenu(markdownMenu); - - initMarkdownitOptionMenu(markdownMenu); - - markdownMenu->addSeparator(); - - initRenderStyleMenu(markdownMenu); - - initRenderBackgroundMenu(markdownMenu); - - initCodeBlockStyleMenu(markdownMenu); - - QAction *constrainImageAct = new QAction(tr("Constrain The Width of Images"), this); - constrainImageAct->setToolTip(tr("Constrain the width of images to the window in read mode (re-open current tabs to make it work)")); - constrainImageAct->setCheckable(true); - connect(constrainImageAct, &QAction::triggered, - this, &VMainWindow::enableImageConstraint); - markdownMenu->addAction(constrainImageAct); - constrainImageAct->setChecked(g_config->getEnableImageConstraint()); - - QAction *imageCaptionAct = new QAction(tr("Enable Image Caption"), this); - imageCaptionAct->setToolTip(tr("Center the images and display the alt text as caption (re-open current tabs to make it work)")); - imageCaptionAct->setCheckable(true); - connect(imageCaptionAct, &QAction::triggered, - this, &VMainWindow::enableImageCaption); - markdownMenu->addAction(imageCaptionAct); - imageCaptionAct->setChecked(g_config->getEnableImageCaption()); - - markdownMenu->addSeparator(); - - QAction *mermaidAct = new QAction(tr("&Mermaid Diagram"), this); - mermaidAct->setToolTip(tr("Enable Mermaid for graph and diagram")); - mermaidAct->setCheckable(true); - connect(mermaidAct, &QAction::triggered, - this, &VMainWindow::enableMermaid); - markdownMenu->addAction(mermaidAct); - - mermaidAct->setChecked(g_config->getEnableMermaid()); - - QAction *flowchartAct = new QAction(tr("&Flowchart.js"), this); - flowchartAct->setToolTip(tr("Enable Flowchart.js for flowchart diagram")); - flowchartAct->setCheckable(true); - connect(flowchartAct, &QAction::triggered, - this, [this](bool p_enabled){ - g_config->setEnableFlowchart(p_enabled); - }); - markdownMenu->addAction(flowchartAct); - flowchartAct->setChecked(g_config->getEnableFlowchart()); - - QAction *mathjaxAct = new QAction(tr("Math&Jax"), this); - mathjaxAct->setToolTip(tr("Enable MathJax for math support in Markdown")); - mathjaxAct->setCheckable(true); - connect(mathjaxAct, &QAction::triggered, - this, &VMainWindow::enableMathjax); - markdownMenu->addAction(mathjaxAct); - - mathjaxAct->setChecked(g_config->getEnableMathjax()); - - markdownMenu->addSeparator(); - - QAction *codeBlockAct = new QAction(tr("Highlight Code Blocks In Edit Mode"), this); - codeBlockAct->setToolTip(tr("Enable syntax highlight within code blocks in edit mode")); - codeBlockAct->setCheckable(true); - connect(codeBlockAct, &QAction::triggered, - this, &VMainWindow::enableCodeBlockHighlight); - markdownMenu->addAction(codeBlockAct); - codeBlockAct->setChecked(g_config->getEnableCodeBlockHighlight()); - - QAction *lineNumberAct = new QAction(tr("Display Line Number In Code Blocks"), this); - lineNumberAct->setToolTip(tr("Enable line number in code blocks in read mode")); - lineNumberAct->setCheckable(true); - connect(lineNumberAct, &QAction::triggered, - this, [this](bool p_checked){ - g_config->setEnableCodeBlockLineNumber(p_checked); - }); - markdownMenu->addAction(lineNumberAct); - lineNumberAct->setChecked(g_config->getEnableCodeBlockLineNumber()); - - QAction *previewImageAct = new QAction(tr("Preview Images In Edit Mode"), this); - previewImageAct->setToolTip(tr("Enable image preview in edit mode (re-open current tabs to make it work)")); - previewImageAct->setCheckable(true); - connect(previewImageAct, &QAction::triggered, - this, &VMainWindow::enableImagePreview); - markdownMenu->addAction(previewImageAct); - previewImageAct->setChecked(g_config->getEnablePreviewImages()); - - QAction *previewWidthAct = new QAction(tr("Constrain The Width Of Previewed Images"), this); - previewWidthAct->setToolTip(tr("Constrain the width of previewed images to the edit window in edit mode")); - previewWidthAct->setCheckable(true); - connect(previewWidthAct, &QAction::triggered, - this, &VMainWindow::enableImagePreviewConstraint); - markdownMenu->addAction(previewWidthAct); - previewWidthAct->setChecked(g_config->getEnablePreviewImageConstraint()); -} - -void VMainWindow::initViewMenu() -{ - viewMenu = menuBar()->addMenu(tr("&View")); - viewMenu->setToolTipsVisible(true); -} - -void VMainWindow::initFileMenu() -{ - QMenu *fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->setToolTipsVisible(true); - - // Open external files. - QAction *openAct = new QAction(tr("&Open"), this); - openAct->setToolTip(tr("Open external file to edit")); - connect(openAct, &QAction::triggered, - this, [this](){ - static QString lastPath = QDir::homePath(); - QStringList files = QFileDialog::getOpenFileNames(this, - tr("Select External Files To Open"), - lastPath); - - if (files.isEmpty()) { - return; - } - - // Update lastPath - lastPath = QFileInfo(files[0]).path(); - - openFiles(VUtils::filterFilePathsToOpen(files)); - }); - - fileMenu->addAction(openAct); - - // Import notes from files. - m_importNoteAct = newAction(VIconUtils::menuIcon(":/resources/icons/import_note.svg"), - tr("&New Notes From Files"), this); - m_importNoteAct->setToolTip(tr("Create notes from external files in current folder by copy")); - connect(m_importNoteAct, &QAction::triggered, - this, &VMainWindow::importNoteFromFile); - m_importNoteAct->setEnabled(false); - - fileMenu->addAction(m_importNoteAct); - - fileMenu->addSeparator(); - - // Export as PDF. - m_exportAsPDFAct = new QAction(tr("Export As &PDF"), this); - m_exportAsPDFAct->setToolTip(tr("Export current note as PDF file")); - connect(m_exportAsPDFAct, &QAction::triggered, - this, &VMainWindow::exportAsPDF); - m_exportAsPDFAct->setEnabled(false); - - fileMenu->addAction(m_exportAsPDFAct); - - fileMenu->addSeparator(); - - // Print. - m_printAct = new QAction(VIconUtils::menuIcon(":/resources/icons/print.svg"), - tr("&Print"), this); - m_printAct->setToolTip(tr("Print current note")); - connect(m_printAct, &QAction::triggered, - this, &VMainWindow::printNote); - m_printAct->setEnabled(false); - - // Themes. - initThemeMenu(fileMenu); - - // Settings. - QAction *settingsAct = newAction(VIconUtils::menuIcon(":/resources/icons/settings.svg"), - tr("&Settings"), this); - settingsAct->setToolTip(tr("View and change settings for VNote")); - settingsAct->setMenuRole(QAction::PreferencesRole); - connect(settingsAct, &QAction::triggered, - this, &VMainWindow::viewSettings); - - fileMenu->addAction(settingsAct); - - QAction *openConfigAct = new QAction(tr("Open Configuration Folder"), this); - openConfigAct->setToolTip(tr("Open configuration folder of VNote")); - connect(openConfigAct, &QAction::triggered, - this, [this](){ - QUrl url = QUrl::fromLocalFile(g_config->getConfigFolder()); - QDesktopServices::openUrl(url); - }); - - fileMenu->addAction(openConfigAct); - - QAction *customShortcutAct = new QAction(tr("Custom Shortcuts"), this); - customShortcutAct->setToolTip(tr("Custom some standard shortcuts")); - connect(customShortcutAct, &QAction::triggered, - this, [this](){ - int ret = VUtils::showMessage(QMessageBox::Information, - tr("Custom Shortcuts"), - tr("VNote supports customing some standard shorcuts by " - "editing user's configuration file (vnote.ini). Please " - "reference the shortcuts help documentation for more " - "information."), - tr("Click \"OK\" to custom shortcuts."), - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Ok, - this); - - if (ret == QMessageBox::Ok) { -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - // On macOS, it seems that we could not open that ini file directly. - QUrl url = QUrl::fromLocalFile(g_config->getConfigFolder()); -#else - QUrl url = QUrl::fromLocalFile(g_config->getConfigFilePath()); -#endif - QDesktopServices::openUrl(url); - } - }); - - fileMenu->addAction(customShortcutAct); - - fileMenu->addSeparator(); - - // Exit. - QAction *exitAct = new QAction(tr("&Quit"), this); - exitAct->setToolTip(tr("Quit VNote")); - exitAct->setShortcut(QKeySequence("Ctrl+Q")); - exitAct->setMenuRole(QAction::QuitRole); - connect(exitAct, &QAction::triggered, - this, &VMainWindow::quitApp); - - fileMenu->addAction(exitAct); -} - -void VMainWindow::quitApp() -{ - m_requestQuit = true; - close(); -} - -void VMainWindow::initEditMenu() -{ - QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); - editMenu->setToolTipsVisible(true); - - // Find/Replace. - m_findReplaceAct = newAction(VIconUtils::menuIcon(":/resources/icons/find_replace.svg"), - tr("Find/Replace"), this); - m_findReplaceAct->setToolTip(tr("Open Find/Replace dialog to search in current note")); - QString keySeq = g_config->getShortcutKeySequence("Find"); - qDebug() << "set Find shortcut to" << keySeq; - m_findReplaceAct->setShortcut(QKeySequence(keySeq)); - connect(m_findReplaceAct, &QAction::triggered, - this, &VMainWindow::openFindDialog); - - m_findNextAct = new QAction(tr("Find Next"), this); - m_findNextAct->setToolTip(tr("Find next occurence")); - keySeq = g_config->getShortcutKeySequence("FindNext"); - qDebug() << "set FindNext shortcut to" << keySeq; - m_findNextAct->setShortcut(QKeySequence(keySeq)); - connect(m_findNextAct, SIGNAL(triggered(bool)), - m_findReplaceDialog, SLOT(findNext())); - - m_findPreviousAct = new QAction(tr("Find Previous"), this); - m_findPreviousAct->setToolTip(tr("Find previous occurence")); - keySeq = g_config->getShortcutKeySequence("FindPrevious"); - qDebug() << "set FindPrevious shortcut to" << keySeq; - m_findPreviousAct->setShortcut(QKeySequence(keySeq)); - connect(m_findPreviousAct, SIGNAL(triggered(bool)), - m_findReplaceDialog, SLOT(findPrevious())); - - m_replaceAct = new QAction(tr("Replace"), this); - m_replaceAct->setToolTip(tr("Replace current occurence")); - connect(m_replaceAct, SIGNAL(triggered(bool)), - m_findReplaceDialog, SLOT(replace())); - - m_replaceFindAct = new QAction(tr("Replace && Find"), this); - m_replaceFindAct->setToolTip(tr("Replace current occurence and find the next one")); - connect(m_replaceFindAct, SIGNAL(triggered(bool)), - m_findReplaceDialog, SLOT(replaceFind())); - - m_replaceAllAct = new QAction(tr("Replace All"), this); - m_replaceAllAct->setToolTip(tr("Replace all occurences in current note")); - connect(m_replaceAllAct, SIGNAL(triggered(bool)), - m_findReplaceDialog, SLOT(replaceAll())); - - QAction *searchedWordAct = new QAction(tr("Highlight Searched Pattern"), this); - searchedWordAct->setToolTip(tr("Highlight all occurences of searched pattern")); - searchedWordAct->setCheckable(true); - connect(searchedWordAct, &QAction::triggered, - this, &VMainWindow::changeHighlightSearchedWord); - - // Expand Tab into spaces. - QAction *expandTabAct = new QAction(tr("&Expand Tab"), this); - expandTabAct->setToolTip(tr("Expand entered Tab to spaces")); - expandTabAct->setCheckable(true); - connect(expandTabAct, &QAction::triggered, - this, &VMainWindow::changeExpandTab); - - // Tab stop width. - QActionGroup *tabStopWidthAct = new QActionGroup(this); - QAction *twoSpaceTabAct = new QAction(tr("2 Spaces"), tabStopWidthAct); - twoSpaceTabAct->setToolTip(tr("Expand Tab to 2 spaces")); - twoSpaceTabAct->setCheckable(true); - twoSpaceTabAct->setData(2); - QAction *fourSpaceTabAct = new QAction(tr("4 Spaces"), tabStopWidthAct); - fourSpaceTabAct->setToolTip(tr("Expand Tab to 4 spaces")); - fourSpaceTabAct->setCheckable(true); - fourSpaceTabAct->setData(4); - QAction *eightSpaceTabAct = new QAction(tr("8 Spaces"), tabStopWidthAct); - eightSpaceTabAct->setToolTip(tr("Expand Tab to 8 spaces")); - eightSpaceTabAct->setCheckable(true); - eightSpaceTabAct->setData(8); - connect(tabStopWidthAct, &QActionGroup::triggered, - this, &VMainWindow::setTabStopWidth); - - // Auto Indent. - m_autoIndentAct = new QAction(tr("Auto Indent"), this); - m_autoIndentAct->setToolTip(tr("Indent automatically when inserting a new line")); - m_autoIndentAct->setCheckable(true); - connect(m_autoIndentAct, &QAction::triggered, - this, &VMainWindow::changeAutoIndent); - - // Auto List. - QAction *autoListAct = new QAction(tr("Auto List"), this); - autoListAct->setToolTip(tr("Continue the list automatically when inserting a new line")); - autoListAct->setCheckable(true); - connect(autoListAct, &QAction::triggered, - this, &VMainWindow::changeAutoList); - - // Vim Mode. - QAction *vimAct = new QAction(tr("Vim Mode"), this); - vimAct->setToolTip(tr("Enable Vim mode for editing (re-open current tabs to make it work)")); - vimAct->setCheckable(true); - connect(vimAct, &QAction::triggered, - this, &VMainWindow::changeVimMode); - - // Smart input method in Vim mode. - QAction *smartImAct = new QAction(tr("Smart Input Method In Vim Mode"), this); - smartImAct->setToolTip(tr("Disable input method when leaving Insert mode in Vim mode")); - smartImAct->setCheckable(true); - connect(smartImAct, &QAction::triggered, - this, [this](bool p_checked){ - g_config->setEnableSmartImInVimMode(p_checked); - }); - - // Highlight current cursor line. - QAction *cursorLineAct = new QAction(tr("Highlight Cursor Line"), this); - cursorLineAct->setToolTip(tr("Highlight current cursor line")); - cursorLineAct->setCheckable(true); - connect(cursorLineAct, &QAction::triggered, - this, &VMainWindow::changeHighlightCursorLine); - - // Highlight selected word. - QAction *selectedWordAct = new QAction(tr("Highlight Selected Words"), this); - selectedWordAct->setToolTip(tr("Highlight all occurences of selected words")); - selectedWordAct->setCheckable(true); - connect(selectedWordAct, &QAction::triggered, - this, &VMainWindow::changeHighlightSelectedWord); - - // Highlight trailing space. - QAction *trailingSapceAct = new QAction(tr("Highlight Trailing Sapces"), this); - trailingSapceAct->setToolTip(tr("Highlight all the spaces at the end of a line")); - trailingSapceAct->setCheckable(true); - connect(trailingSapceAct, &QAction::triggered, - this, &VMainWindow::changeHighlightTrailingSapce); - - QMenu *findReplaceMenu = editMenu->addMenu(tr("Find/Replace")); - findReplaceMenu->setToolTipsVisible(true); - findReplaceMenu->addAction(m_findReplaceAct); - findReplaceMenu->addAction(m_findNextAct); - findReplaceMenu->addAction(m_findPreviousAct); - findReplaceMenu->addAction(m_replaceAct); - findReplaceMenu->addAction(m_replaceFindAct); - findReplaceMenu->addAction(m_replaceAllAct); - findReplaceMenu->addSeparator(); - findReplaceMenu->addAction(searchedWordAct); - searchedWordAct->setChecked(g_config->getHighlightSearchedWord()); - - m_findReplaceAct->setEnabled(false); - m_findNextAct->setEnabled(false); - m_findPreviousAct->setEnabled(false); - m_replaceAct->setEnabled(false); - m_replaceFindAct->setEnabled(false); - m_replaceAllAct->setEnabled(false); - - editMenu->addSeparator(); - editMenu->addAction(expandTabAct); - if (g_config->getIsExpandTab()) { - expandTabAct->setChecked(true); - } else { - expandTabAct->setChecked(false); - } - - QMenu *tabStopWidthMenu = editMenu->addMenu(tr("Tab Stop Width")); - tabStopWidthMenu->setToolTipsVisible(true); - tabStopWidthMenu->addAction(twoSpaceTabAct); - tabStopWidthMenu->addAction(fourSpaceTabAct); - tabStopWidthMenu->addAction(eightSpaceTabAct); - int tabStopWidth = g_config->getTabStopWidth(); - switch (tabStopWidth) { - case 2: - twoSpaceTabAct->setChecked(true); - break; - case 4: - fourSpaceTabAct->setChecked(true); - break; - case 8: - eightSpaceTabAct->setChecked(true); - break; - default: - qWarning() << "unsupported tab stop width" << tabStopWidth << "in config"; - } - - editMenu->addAction(m_autoIndentAct); - m_autoIndentAct->setChecked(g_config->getAutoIndent()); - - editMenu->addAction(autoListAct); - if (g_config->getAutoList()) { - // Let the trigger handler to trigger m_autoIndentAct, too. - autoListAct->trigger(); - } - Q_ASSERT(!(autoListAct->isChecked() && !m_autoIndentAct->isChecked())); - - editMenu->addAction(vimAct); - vimAct->setChecked(g_config->getEnableVimMode()); - - editMenu->addAction(smartImAct); - smartImAct->setChecked(g_config->getEnableSmartImInVimMode()); - - editMenu->addSeparator(); - - initEditorStyleMenu(editMenu); - - initEditorBackgroundMenu(editMenu); - - initEditorLineNumberMenu(editMenu); - - editMenu->addAction(cursorLineAct); - cursorLineAct->setChecked(g_config->getHighlightCursorLine()); - - editMenu->addAction(selectedWordAct); - selectedWordAct->setChecked(g_config->getHighlightSelectedWord()); - - editMenu->addAction(trailingSapceAct); - trailingSapceAct->setChecked(g_config->getEnableTrailingSpaceHighlight()); -} - -void VMainWindow::initDockWindows() -{ - toolDock = new QDockWidget(tr("Tools"), this); - toolDock->setObjectName("ToolsDock"); - toolDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - - // Outline tree. - outline = new VOutline(this); - connect(editArea, &VEditArea::outlineChanged, - outline, &VOutline::updateOutline); - connect(editArea, &VEditArea::currentHeaderChanged, - outline, &VOutline::updateCurrentHeader); - connect(outline, &VOutline::outlineItemActivated, - editArea, &VEditArea::scrollToHeader); - - // Snippets. - m_snippetList = new VSnippetList(this); - - m_toolBox = new VToolBox(this); - m_toolBox->addItem(outline, - ":/resources/icons/outline.svg", - tr("Outline")); - m_toolBox->addItem(m_snippetList, - ":/resources/icons/snippets.svg", - tr("Snippets")); - - toolDock->setWidget(m_toolBox); - addDockWidget(Qt::RightDockWidgetArea, toolDock); - - QAction *toggleAct = toolDock->toggleViewAction(); - toggleAct->setToolTip(tr("Toggle the tools dock widget")); - viewMenu->addAction(toggleAct); -} - -void VMainWindow::initAvatar() -{ - m_avatar = new VAvatar(this); - m_avatar->setAvatarPixmap(":/resources/icons/vnote.svg"); - m_avatar->setColor(g_palette->color("avatar_border_bg"), - g_palette->color("avatar_fg"), - g_palette->color("avatar_bg")); - m_avatar->hide(); -} - -void VMainWindow::importNoteFromFile() -{ - static QString lastPath = QDir::homePath(); - QStringList files = QFileDialog::getOpenFileNames(this, - tr("Select Files To Create Notes"), - lastPath); - if (files.isEmpty()) { - return; - } - - // Update lastPath - lastPath = QFileInfo(files[0]).path(); - - QString msg; - if (!m_fileList->importFiles(files, &msg)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to create notes for all the files."), - msg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } else { - int cnt = files.size(); - showStatusMessage(tr("%1 %2 created from external files") - .arg(cnt) - .arg(cnt > 1 ? tr("notes") : tr("note"))); - } -} - -void VMainWindow::changeMarkdownConverter(QAction *action) -{ - if (!action) { - return; - } - - MarkdownConverterType type = (MarkdownConverterType)action->data().toInt(); - - qDebug() << "switch to converter" << type; - - g_config->setMarkdownConverterType(type); -} - -void VMainWindow::aboutMessage() -{ - QString info = tr("v%1").arg(VConfigManager::c_version); - info += "

    "; - info += tr("VNote is a Vim-inspired note-taking application for Markdown."); - info += "
    "; - info += tr("Please visit Github for more information."); - QMessageBox::about(this, tr("About VNote"), info); -} - -void VMainWindow::changeExpandTab(bool checked) -{ - g_config->setIsExpandTab(checked); -} - -void VMainWindow::enableMermaid(bool p_checked) -{ - g_config->setEnableMermaid(p_checked); -} - -void VMainWindow::enableMathjax(bool p_checked) -{ - g_config->setEnableMathjax(p_checked); -} - -void VMainWindow::changeHighlightCursorLine(bool p_checked) -{ - g_config->setHighlightCursorLine(p_checked); -} - -void VMainWindow::changeHighlightSelectedWord(bool p_checked) -{ - g_config->setHighlightSelectedWord(p_checked); -} - -void VMainWindow::changeHighlightSearchedWord(bool p_checked) -{ - g_config->setHighlightSearchedWord(p_checked); -} - -void VMainWindow::changeHighlightTrailingSapce(bool p_checked) -{ - g_config->setEnableTrailingSapceHighlight(p_checked); -} - -void VMainWindow::setTabStopWidth(QAction *action) -{ - if (!action) { - return; - } - g_config->setTabStopWidth(action->data().toInt()); -} - -void VMainWindow::setEditorBackgroundColor(QAction *action) -{ - if (!action) { - return; - } - - g_config->setCurBackgroundColor(action->data().toString()); -} - -void VMainWindow::initPredefinedColorPixmaps() -{ - const QVector &bgColors = g_config->getPredefinedColors(); - predefinedColorPixmaps.clear(); - int size = 256; - for (int i = 0; i < bgColors.size(); ++i) { - // Generate QPixmap filled in this color - QColor color(VUtils::QRgbFromString(bgColors[i].rgb)); - QPixmap pixmap(size, size); - pixmap.fill(color); - predefinedColorPixmaps.append(pixmap); - } -} - -void VMainWindow::initConverterMenu(QMenu *p_menu) -{ - QMenu *converterMenu = p_menu->addMenu(tr("&Converter")); - converterMenu->setToolTipsVisible(true); - - QActionGroup *converterAct = new QActionGroup(this); - QAction *markedAct = new QAction(tr("Marked"), converterAct); - markedAct->setToolTip(tr("Use Marked to convert Markdown to HTML (re-open current tabs to make it work)")); - markedAct->setCheckable(true); - markedAct->setData(int(MarkdownConverterType::Marked)); - - QAction *hoedownAct = new QAction(tr("Hoedown"), converterAct); - hoedownAct->setToolTip(tr("Use Hoedown to convert Markdown to HTML (re-open current tabs to make it work)")); - hoedownAct->setCheckable(true); - hoedownAct->setData(int(MarkdownConverterType::Hoedown)); - - QAction *markdownitAct = new QAction(tr("Markdown-it"), converterAct); - markdownitAct->setToolTip(tr("Use Markdown-it to convert Markdown to HTML (re-open current tabs to make it work)")); - markdownitAct->setCheckable(true); - markdownitAct->setData(int(MarkdownConverterType::MarkdownIt)); - - QAction *showdownAct = new QAction(tr("Showdown"), converterAct); - showdownAct->setToolTip(tr("Use Showdown to convert Markdown to HTML (re-open current tabs to make it work)")); - showdownAct->setCheckable(true); - showdownAct->setData(int(MarkdownConverterType::Showdown)); - - connect(converterAct, &QActionGroup::triggered, - this, &VMainWindow::changeMarkdownConverter); - converterMenu->addAction(hoedownAct); - converterMenu->addAction(markedAct); - converterMenu->addAction(markdownitAct); - converterMenu->addAction(showdownAct); - - MarkdownConverterType converterType = g_config->getMdConverterType(); - switch (converterType) { - case MarkdownConverterType::Marked: - markedAct->setChecked(true); - break; - - case MarkdownConverterType::Hoedown: - hoedownAct->setChecked(true); - break; - - case MarkdownConverterType::MarkdownIt: - markdownitAct->setChecked(true); - break; - - case MarkdownConverterType::Showdown: - showdownAct->setChecked(true); - break; - - default: - Q_ASSERT(false); - } -} - -void VMainWindow::initMarkdownitOptionMenu(QMenu *p_menu) -{ - QMenu *optMenu = p_menu->addMenu(tr("Markdown-it Options")); - optMenu->setToolTipsVisible(true); - - MarkdownitOption opt = g_config->getMarkdownitOption(); - - QAction *htmlAct = new QAction(tr("HTML"), this); - htmlAct->setToolTip(tr("Enable HTML tags in source")); - htmlAct->setCheckable(true); - htmlAct->setChecked(opt.m_html); - connect(htmlAct, &QAction::triggered, - this, [this](bool p_checked) { - MarkdownitOption opt = g_config->getMarkdownitOption(); - opt.m_html = p_checked; - g_config->setMarkdownitOption(opt); - }); - - QAction *breaksAct = new QAction(tr("Line Break"), this); - breaksAct->setToolTip(tr("Convert '\\n' in paragraphs into line break")); - breaksAct->setCheckable(true); - breaksAct->setChecked(opt.m_breaks); - connect(breaksAct, &QAction::triggered, - this, [this](bool p_checked) { - MarkdownitOption opt = g_config->getMarkdownitOption(); - opt.m_breaks = p_checked; - g_config->setMarkdownitOption(opt); - }); - - QAction *linkifyAct = new QAction(tr("Linkify"), this); - linkifyAct->setToolTip(tr("Convert URL-like text into links")); - linkifyAct->setCheckable(true); - linkifyAct->setChecked(opt.m_linkify); - connect(linkifyAct, &QAction::triggered, - this, [this](bool p_checked) { - MarkdownitOption opt = g_config->getMarkdownitOption(); - opt.m_linkify = p_checked; - g_config->setMarkdownitOption(opt); - }); - - optMenu->addAction(htmlAct); - optMenu->addAction(breaksAct); - optMenu->addAction(linkifyAct); -} - -void VMainWindow::initRenderBackgroundMenu(QMenu *menu) -{ - QActionGroup *renderBackgroundAct = new QActionGroup(this); - connect(renderBackgroundAct, &QActionGroup::triggered, - this, &VMainWindow::setRenderBackgroundColor); - - QMenu *renderBgMenu = menu->addMenu(tr("&Rendering Background")); - renderBgMenu->setToolTipsVisible(true); - const QString &curBgColor = g_config->getCurRenderBackgroundColor(); - QAction *tmpAct = new QAction(tr("System"), renderBackgroundAct); - tmpAct->setToolTip(tr("Use system's background color configuration for Markdown rendering")); - tmpAct->setCheckable(true); - tmpAct->setData("System"); - if (curBgColor == "System") { - tmpAct->setChecked(true); - } - renderBgMenu->addAction(tmpAct); - - const QVector &bgColors = g_config->getPredefinedColors(); - for (int i = 0; i < bgColors.size(); ++i) { - tmpAct = new QAction(bgColors[i].name, renderBackgroundAct); - tmpAct->setToolTip(tr("Set as the background color for Markdown rendering")); - tmpAct->setCheckable(true); - tmpAct->setData(bgColors[i].name); - -#if !defined(Q_OS_MACOS) && !defined(Q_OS_MAC) - tmpAct->setIcon(QIcon(predefinedColorPixmaps[i])); -#endif - - if (curBgColor == bgColors[i].name) { - tmpAct->setChecked(true); - } - - renderBgMenu->addAction(tmpAct); - } -} - -void VMainWindow::initRenderStyleMenu(QMenu *p_menu) -{ - QMenu *styleMenu = p_menu->addMenu(tr("Rendering &Style")); - styleMenu->setToolTipsVisible(true); - - QActionGroup *ag = new QActionGroup(this); - connect(ag, &QActionGroup::triggered, - this, [this](QAction *p_action) { - if (!p_action) { - return; - } - - QString data = p_action->data().toString(); - g_config->setCssStyle(data); - vnote->updateTemplate(); - }); - - QList styles = g_config->getCssStyles(); - QString curStyle = g_config->getCssStyle(); - for (auto const &style : styles) { - QAction *act = new QAction(style, ag); - act->setToolTip(tr("Set as the CSS style for Markdown rendering " - "(re-open current tabs to make it work)")); - act->setCheckable(true); - act->setData(style); - - // Add it to the menu. - styleMenu->addAction(act); - - if (curStyle == style) { - act->setChecked(true); - } - } -} - -void VMainWindow::initCodeBlockStyleMenu(QMenu *p_menu) -{ - QMenu *styleMenu = p_menu->addMenu(tr("Code Block Style")); - styleMenu->setToolTipsVisible(true); - - QActionGroup *ag = new QActionGroup(this); - connect(ag, &QActionGroup::triggered, - this, [this](QAction *p_action) { - if (!p_action) { - return; - } - - QString data = p_action->data().toString(); - g_config->setCodeBlockCssStyle(data); - vnote->updateTemplate(); - }); - - QList styles = g_config->getCodeBlockCssStyles(); - QString curStyle = g_config->getCodeBlockCssStyle(); - for (auto const &style : styles) { - QAction *act = new QAction(style, ag); - act->setToolTip(tr("Set as the code block CSS style for Markdown rendering " - "(re-open current tabs to make it work)")); - act->setCheckable(true); - act->setData(style); - - // Add it to the menu. - styleMenu->addAction(act); - - if (curStyle == style) { - act->setChecked(true); - } - } -} - -void VMainWindow::initEditorBackgroundMenu(QMenu *menu) -{ - QMenu *backgroundColorMenu = menu->addMenu(tr("&Background Color")); - backgroundColorMenu->setToolTipsVisible(true); - - QActionGroup *backgroundColorAct = new QActionGroup(this); - connect(backgroundColorAct, &QActionGroup::triggered, - this, &VMainWindow::setEditorBackgroundColor); - - // System background color - const QString &curBgColor = g_config->getCurBackgroundColor(); - QAction *tmpAct = new QAction(tr("System"), backgroundColorAct); - tmpAct->setToolTip(tr("Use system's background color configuration for editor")); - tmpAct->setCheckable(true); - tmpAct->setData("System"); - if (curBgColor == "System") { - tmpAct->setChecked(true); - } - backgroundColorMenu->addAction(tmpAct); - const QVector &bgColors = g_config->getPredefinedColors(); - for (int i = 0; i < bgColors.size(); ++i) { - tmpAct = new QAction(bgColors[i].name, backgroundColorAct); - tmpAct->setToolTip(tr("Set as the background color for editor")); - tmpAct->setCheckable(true); - tmpAct->setData(bgColors[i].name); -#if !defined(Q_OS_MACOS) && !defined(Q_OS_MAC) - tmpAct->setIcon(QIcon(predefinedColorPixmaps[i])); -#endif - if (curBgColor == bgColors[i].name) { - tmpAct->setChecked(true); - } - - backgroundColorMenu->addAction(tmpAct); - } -} - -void VMainWindow::initEditorLineNumberMenu(QMenu *p_menu) -{ - QMenu *lineNumMenu = p_menu->addMenu(tr("Line Number")); - lineNumMenu->setToolTipsVisible(true); - - QActionGroup *lineNumAct = new QActionGroup(lineNumMenu); - connect(lineNumAct, &QActionGroup::triggered, - this, [this](QAction *p_action){ - if (!p_action) { - return; - } - - g_config->setEditorLineNumber(p_action->data().toInt()); - emit editorConfigUpdated(); - }); - - int lineNumberMode = g_config->getEditorLineNumber(); - - QAction *act = lineNumAct->addAction(tr("None")); - act->setToolTip(tr("Do not display line number in edit mode")); - act->setCheckable(true); - act->setData(0); - lineNumMenu->addAction(act); - if (lineNumberMode == 0) { - act->setChecked(true); - } - - act = lineNumAct->addAction(tr("Absolute")); - act->setToolTip(tr("Display absolute line number in edit mode")); - act->setCheckable(true); - act->setData(1); - lineNumMenu->addAction(act); - if (lineNumberMode == 1) { - act->setChecked(true); - } - - act = lineNumAct->addAction(tr("Relative")); - act->setToolTip(tr("Display line number relative to current cursor line in edit mode")); - act->setCheckable(true); - act->setData(2); - lineNumMenu->addAction(act); - if (lineNumberMode == 2) { - act->setChecked(true); - } - - act = lineNumAct->addAction(tr("CodeBlock")); - act->setToolTip(tr("Display line number in code block in edit mode (for Markdown only)")); - act->setCheckable(true); - act->setData(3); - lineNumMenu->addAction(act); - if (lineNumberMode == 3) { - act->setChecked(true); - } -} - -void VMainWindow::initEditorStyleMenu(QMenu *p_menu) -{ - QMenu *styleMenu = p_menu->addMenu(tr("Editor &Style")); - styleMenu->setToolTipsVisible(true); - - QActionGroup *ag = new QActionGroup(this); - connect(ag, &QActionGroup::triggered, - this, [this](QAction *p_action) { - if (!p_action) { - return; - } - - QString data = p_action->data().toString(); - g_config->setEditorStyle(data); - }); - - QList styles = g_config->getEditorStyles(); - QString style = g_config->getEditorStyle(); - for (auto const &item : styles) { - QAction *act = new QAction(item, ag); - act->setToolTip(tr("Set as the editor style (re-open current tabs to make it work)")); - act->setCheckable(true); - act->setData(item); - - // Add it to the menu. - styleMenu->addAction(act); - - if (style == item) { - act->setChecked(true); - } - } -} - -void VMainWindow::setRenderBackgroundColor(QAction *action) -{ - if (!action) { - return; - } - g_config->setCurRenderBackgroundColor(action->data().toString()); - vnote->updateTemplate(); -} - -void VMainWindow::updateActionsStateFromTab(const VEditTab *p_tab) -{ - const VFile *file = p_tab ? p_tab->getFile() : NULL; - bool editMode = p_tab ? p_tab->isEditMode() : false; - bool systemFile = file - && file->getType() == FileType::Orphan - && dynamic_cast(file)->isSystemFile(); - - m_printAct->setEnabled(file && file->getDocType() == DocType::Markdown); - m_exportAsPDFAct->setEnabled(file && file->getDocType() == DocType::Markdown); - - discardExitAct->setVisible(file && editMode); - saveExitAct->setVisible(file && editMode); - editNoteAct->setEnabled(file && !editMode); - editNoteAct->setVisible(!saveExitAct->isVisible()); - saveNoteAct->setEnabled(file && editMode && file->isModifiable()); - deleteNoteAct->setEnabled(file && file->getType() == FileType::Note); - noteInfoAct->setEnabled(file && !systemFile); - - m_attachmentBtn->setEnabled(file && file->getType() == FileType::Note); - - m_headingBtn->setEnabled(file && editMode); - - setActionsEnabled(m_editToolBar, file && editMode); - - // Handle heading sequence act independently. - m_headingSequenceAct->setEnabled(isHeadingSequenceApplicable()); - const VMdTab *mdTab = dynamic_cast(p_tab); - m_headingSequenceAct->setChecked(mdTab && mdTab->isHeadingSequenceEnabled()); - - // Find/Replace - m_findReplaceAct->setEnabled(file); - m_findNextAct->setEnabled(file); - m_findPreviousAct->setEnabled(file); - m_replaceAct->setEnabled(file && editMode); - m_replaceFindAct->setEnabled(file && editMode); - m_replaceAllAct->setEnabled(file && editMode); - - if (!file) { - m_findReplaceDialog->closeDialog(); - } -} - -void VMainWindow::handleAreaTabStatusUpdated(const VEditTabInfo &p_info) -{ - m_curTab = p_info.m_editTab; - if (m_curTab) { - m_curFile = m_curTab->getFile(); - } else { - m_curFile = NULL; - } - - if (p_info.m_type == VEditTabInfo::InfoType::All) { - updateActionsStateFromTab(m_curTab); - - m_attachmentList->setFile(dynamic_cast(m_curFile.data())); - - QString title; - if (m_curFile) { - m_findReplaceDialog->updateState(m_curFile->getDocType(), - m_curTab->isEditMode()); - - if (m_curFile->getType() == FileType::Note) { - const VNoteFile *tmpFile = dynamic_cast((VFile *)m_curFile); - title = QString("[%1] %2").arg(tmpFile->getNotebookName()).arg(tmpFile->fetchPath()); - } else { - title = QString("%1").arg(m_curFile->fetchPath()); - } - - if (!m_curFile->isModifiable()) { - title.append('#'); - } - - if (m_curTab->isModified()) { - title.append('*'); - } - } - - updateWindowTitle(title); - } - - updateStatusInfo(p_info); -} - -void VMainWindow::onePanelView() -{ - m_panelViewState = PanelViewState::SinglePanel; - g_config->setEnableCompactMode(false); - changePanelView(m_panelViewState); -} - -void VMainWindow::twoPanelView() -{ - m_panelViewState = PanelViewState::TwoPanels; - g_config->setEnableCompactMode(false); - changePanelView(m_panelViewState); -} - -void VMainWindow::compactModeView() -{ - m_panelViewState = PanelViewState::CompactMode; - g_config->setEnableCompactMode(true); - changePanelView(m_panelViewState); -} - -void VMainWindow::enableCompactMode(bool p_enabled) -{ - const int fileListIdx = 1; - bool isCompactMode = m_naviSplitter->indexOf(m_fileList) != -1; - if (p_enabled) { - // Change to compact mode. - if (isCompactMode) { - return; - } - - // Take m_fileList out of m_mainSplitter. - QWidget *tmpWidget = new QWidget(this); - Q_ASSERT(fileListIdx == m_mainSplitter->indexOf(m_fileList)); - m_fileList->hide(); - m_mainSplitter->replaceWidget(fileListIdx, tmpWidget); - tmpWidget->hide(); - - // Insert m_fileList into m_naviSplitter. - QWidget *wid = m_naviSplitter->replaceWidget(fileListIdx, m_fileList); - delete wid; - - m_fileList->show(); - } else { - // Disable compact mode and go back to two panels view. - if (!isCompactMode) { - return; - } - - // Take m_fileList out of m_naviSplitter. - Q_ASSERT(fileListIdx == m_naviSplitter->indexOf(m_fileList)); - QWidget *tmpWidget = new QWidget(this); - m_fileList->hide(); - m_naviSplitter->replaceWidget(fileListIdx, tmpWidget); - tmpWidget->hide(); - - // Insert m_fileList into m_mainSplitter. - QWidget *wid = m_mainSplitter->replaceWidget(fileListIdx, m_fileList); - delete wid; - - m_fileList->show(); - } - - // Set Tab order. - setTabOrder(directoryTree, m_fileList->getContentWidget()); -} - -void VMainWindow::changePanelView(PanelViewState p_state) -{ - switch (p_state) { - case PanelViewState::ExpandMode: - m_mainSplitter->widget(0)->hide(); - m_mainSplitter->widget(1)->hide(); - m_mainSplitter->widget(2)->show(); - break; - - case PanelViewState::SinglePanel: - enableCompactMode(false); - - m_mainSplitter->widget(0)->hide(); - m_mainSplitter->widget(1)->show(); - m_mainSplitter->widget(2)->show(); - break; - - case PanelViewState::TwoPanels: - enableCompactMode(false); - - m_mainSplitter->widget(0)->show(); - m_mainSplitter->widget(1)->show(); - m_mainSplitter->widget(2)->show(); - break; - - case PanelViewState::CompactMode: - m_mainSplitter->widget(0)->show(); - m_mainSplitter->widget(1)->hide(); - m_mainSplitter->widget(2)->show(); - - enableCompactMode(true); - break; - - default: - break; - } - - // Change the action state. - QList acts = m_viewActGroup->actions(); - for (auto & act : acts) { - if (act->data().toInt() == (int)p_state) { - act->setChecked(true); - } else { - act->setChecked(false); - } - } - - if (p_state != PanelViewState::ExpandMode) { - expandViewAct->setChecked(false); - } -} - -void VMainWindow::updateWindowTitle(const QString &str) -{ - QString title = "VNote"; - if (!str.isEmpty()) { - title = title + " - " + str; - } - setWindowTitle(title); -} - -void VMainWindow::curEditFileInfo() -{ - Q_ASSERT(m_curFile); - - if (m_curFile->getType() == FileType::Note) { - VNoteFile *file = dynamic_cast((VFile *)m_curFile); - Q_ASSERT(file); - m_fileList->fileInfo(file); - } else if (m_curFile->getType() == FileType::Orphan) { - VOrphanFile *file = dynamic_cast((VFile *)m_curFile); - Q_ASSERT(file); - if (!file->isSystemFile()) { - editOrphanFileInfo(m_curFile); - } - } -} - -void VMainWindow::deleteCurNote() -{ - if (!m_curFile || m_curFile->getType() != FileType::Note) { - return; - } - - VNoteFile *file = dynamic_cast((VFile *)m_curFile); - m_fileList->deleteFile(file); -} - -void VMainWindow::closeEvent(QCloseEvent *event) -{ - bool isExit = m_requestQuit || !g_config->getMinimizeToStystemTray(); - m_requestQuit = false; - -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - // Do not support minimized to tray on macOS. - isExit = true; -#endif - - if (!isExit && g_config->getMinimizeToStystemTray() == -1) { - // Not initialized yet. Prompt for user. - int ret = VUtils::showMessage(QMessageBox::Information, - tr("Close VNote"), - tr("Do you want to minimize VNote to system tray " - "instead of quitting it when closing VNote?"), - tr("You could change the option in Settings later."), - QMessageBox::Ok | QMessageBox::No | QMessageBox::Cancel, - QMessageBox::Ok, - this); - if (ret == QMessageBox::Ok) { - g_config->setMinimizeToSystemTray(1); - } else if (ret == QMessageBox::No) { - g_config->setMinimizeToSystemTray(0); - isExit = true; - } else { - event->ignore(); - return; - } - } - - if (isVisible()) { - saveStateAndGeometry(); - } - - if (isExit || !m_trayIcon->isVisible()) { - // Get all the opened tabs. - bool saveOpenedNotes = g_config->getStartupPageType() == StartupPageType::ContinueLeftOff; - QVector fileInfos; - QVector tabs; - if (saveOpenedNotes) { - tabs = editArea->getAllTabsInfo(); - - fileInfos.reserve(tabs.size()); - - for (auto const & tab : tabs) { - // Skip system file. - VFile *file = tab.m_editTab->getFile(); - if (file->getType() == FileType::Orphan - && dynamic_cast(file)->isSystemFile()) { - continue; - } - - VFileSessionInfo info = VFileSessionInfo::fromEditTabInfo(&tab); - fileInfos.push_back(info); - - qDebug() << "file session:" << info.m_file << (info.m_mode == OpenFileMode::Edit); - } - } - - if (!editArea->closeAllFiles(false)) { - // Fail to close all the opened files, cancel closing app. - event->ignore(); - return; - } - - if (saveOpenedNotes) { - g_config->setLastOpenedFiles(fileInfos); - } - - QMainWindow::closeEvent(event); - } else { - hide(); - event->ignore(); - } -} - -void VMainWindow::saveStateAndGeometry() -{ - g_config->setMainWindowGeometry(saveGeometry()); - g_config->setMainWindowState(saveState()); - g_config->setToolsDockChecked(toolDock->isVisible()); - - if (m_panelViewState == PanelViewState::CompactMode) { - g_config->setNaviSplitterState(m_naviSplitter->saveState()); - g_config->setMainSplitterState(m_mainSplitter->saveState()); - } else { - // In one panel view, it will save the wrong state that the directory tree - // panel has a width of zero. - changePanelView(PanelViewState::TwoPanels); - g_config->setMainSplitterState(m_mainSplitter->saveState()); - } -} - -void VMainWindow::restoreStateAndGeometry() -{ - const QByteArray &geometry = g_config->getMainWindowGeometry(); - if (!geometry.isEmpty()) { - restoreGeometry(geometry); - } - const QByteArray &state = g_config->getMainWindowState(); - if (!state.isEmpty()) { - restoreState(state); - } - toolDock->setVisible(g_config->getToolsDockChecked()); - - const QByteArray &splitterState = g_config->getMainSplitterState(); - if (!splitterState.isEmpty()) { - m_mainSplitter->restoreState(splitterState); - } - - const QByteArray &naviSplitterState = g_config->getNaviSplitterState(); - if (!naviSplitterState.isEmpty()) { - m_naviSplitter->restoreState(naviSplitterState); - } -} - -void VMainWindow::handleCurrentDirectoryChanged(const VDirectory *p_dir) -{ - newNoteAct->setEnabled(p_dir); - m_importNoteAct->setEnabled(p_dir); -} - -void VMainWindow::handleCurrentNotebookChanged(const VNotebook *p_notebook) -{ - newRootDirAct->setEnabled(p_notebook); -} - -void VMainWindow::resizeEvent(QResizeEvent *event) -{ - repositionAvatar(); - QMainWindow::resizeEvent(event); -} - -void VMainWindow::keyPressEvent(QKeyEvent *event) -{ - int key = event->key(); - Qt::KeyboardModifiers modifiers = event->modifiers(); - if (key == Qt::Key_Escape - || (key == Qt::Key_BracketLeft - && modifiers == Qt::ControlModifier)) { - m_findReplaceDialog->closeDialog(); - event->accept(); - return; - } - QMainWindow::keyPressEvent(event); -} - -void VMainWindow::repositionAvatar() -{ - int diameter = m_mainSplitter->pos().y(); - int x = width() - diameter - 5; - int y = 0; - qDebug() << "avatar:" << diameter << x << y; - m_avatar->setDiameter(diameter); - m_avatar->move(x, y); - m_avatar->show(); -} - -bool VMainWindow::locateFile(VFile *p_file) -{ - bool ret = false; - if (!p_file || p_file->getType() != FileType::Note) { - return ret; - } - - VNoteFile *file = dynamic_cast(p_file); - VNotebook *notebook = file->getNotebook(); - if (notebookSelector->locateNotebook(notebook)) { - while (directoryTree->currentNotebook() != notebook) { - QCoreApplication::sendPostedEvents(); - } - - VDirectory *dir = file->getDirectory(); - if (directoryTree->locateDirectory(dir)) { - while (m_fileList->currentDirectory() != dir) { - QCoreApplication::sendPostedEvents(); - } - - if (m_fileList->locateFile(file)) { - ret = true; - m_fileList->setFocus(); - } - } - } - - // Open the directory and file panels after location. - if (m_panelViewState == PanelViewState::CompactMode) { - compactModeView(); - } else { - twoPanelView(); - } - - return ret; -} - -void VMainWindow::handleFindDialogTextChanged(const QString &p_text, uint /* p_options */) -{ - bool enabled = true; - if (p_text.isEmpty()) { - enabled = false; - } - m_findNextAct->setEnabled(enabled); - m_findPreviousAct->setEnabled(enabled); - m_replaceAct->setEnabled(enabled); - m_replaceFindAct->setEnabled(enabled); - m_replaceAllAct->setEnabled(enabled); -} - -void VMainWindow::openFindDialog() -{ - m_findReplaceDialog->openDialog(editArea->getSelectedText()); -} - -void VMainWindow::viewSettings() -{ - VSettingsDialog settingsDialog(this); - settingsDialog.exec(); -} - -void VMainWindow::closeCurrentFile() -{ - if (m_curFile) { - editArea->closeFile(m_curFile, false); - } -} - -void VMainWindow::changeAutoIndent(bool p_checked) -{ - g_config->setAutoIndent(p_checked); -} - -void VMainWindow::changeAutoList(bool p_checked) -{ - g_config->setAutoList(p_checked); - if (p_checked) { - if (!m_autoIndentAct->isChecked()) { - m_autoIndentAct->trigger(); - } - m_autoIndentAct->setEnabled(false); - } else { - m_autoIndentAct->setEnabled(true); - } -} - -void VMainWindow::changeVimMode(bool p_checked) -{ - g_config->setEnableVimMode(p_checked); -} - -void VMainWindow::enableCodeBlockHighlight(bool p_checked) -{ - g_config->setEnableCodeBlockHighlight(p_checked); -} - -void VMainWindow::enableImagePreview(bool p_checked) -{ - g_config->setEnablePreviewImages(p_checked); - - emit editorConfigUpdated(); -} - -void VMainWindow::enableImagePreviewConstraint(bool p_checked) -{ - g_config->setEnablePreviewImageConstraint(p_checked); - - emit editorConfigUpdated(); -} - -void VMainWindow::enableImageConstraint(bool p_checked) -{ - g_config->setEnableImageConstraint(p_checked); - - vnote->updateTemplate(); -} - -void VMainWindow::enableImageCaption(bool p_checked) -{ - g_config->setEnableImageCaption(p_checked); -} - -void VMainWindow::shortcutsHelp() -{ - QString locale = VUtils::getLocale(); - QString docName = VNote::c_shortcutsDocFile_en; - if (locale == "zh_CN") { - docName = VNote::c_shortcutsDocFile_zh; - } - - VFile *file = vnote->getOrphanFile(docName, false, true); - editArea->openFile(file, OpenFileMode::Read); -} - -void VMainWindow::printNote() -{ - QPrinter printer; - QPrintDialog dialog(&printer, this); - dialog.setWindowTitle(tr("Print Note")); - - V_ASSERT(m_curTab); - - if (m_curFile->getDocType() == DocType::Markdown) { - VMdTab *mdTab = dynamic_cast((VEditTab *)m_curTab); - VWebView *webView = mdTab->getWebViewer(); - - V_ASSERT(webView); - - if (webView->hasSelection()) { - dialog.addEnabledOption(QAbstractPrintDialog::PrintSelection); - } - - if (dialog.exec() != QDialog::Accepted) { - return; - } - } -} - -void VMainWindow::exportAsPDF() -{ - V_ASSERT(m_curTab); - V_ASSERT(m_curFile); - - if (m_curFile->getDocType() == DocType::Markdown) { - VMdTab *mdTab = dynamic_cast((VEditTab *)m_curTab); - VExporter exporter(mdTab->getMarkdownConverterType(), this); - exporter.exportNote(m_curFile, ExportType::PDF); - exporter.exec(); - } -} - -QAction *VMainWindow::newAction(const QIcon &p_icon, - const QString &p_text, - QObject *p_parent) -{ -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - Q_UNUSED(p_icon); - return new QAction(p_text, p_parent); -#else - return new QAction(p_icon, p_text, p_parent); -#endif -} - -void VMainWindow::showStatusMessage(const QString &p_msg) -{ - const int timeout = 3000; - statusBar()->showMessage(p_msg, timeout); -} - -void VMainWindow::updateStatusInfo(const VEditTabInfo &p_info) -{ - if (m_curTab) { - m_tabIndicator->update(p_info); - m_tabIndicator->show(); - - if (m_curTab->isEditMode()) { - if (p_info.m_type == VEditTabInfo::InfoType::All) { - m_curTab->requestUpdateVimStatus(); - } - } else { - m_vimIndicator->hide(); - } - } else { - m_tabIndicator->hide(); - m_vimIndicator->hide(); - } -} - -void VMainWindow::handleVimStatusUpdated(const VVim *p_vim) -{ - m_vimIndicator->update(p_vim, m_curTab); - if (!p_vim || !m_curTab || !m_curTab->isEditMode()) { - m_vimIndicator->hide(); - } else { - m_vimIndicator->show(); - } -} - -bool VMainWindow::tryOpenInternalFile(const QString &p_filePath) -{ - if (p_filePath.isEmpty()) { - return false; - } - - if (QFileInfo::exists(p_filePath)) { - VFile *file = vnote->getInternalFile(p_filePath); - - if (file) { - editArea->openFile(file, OpenFileMode::Read); - return true; - } - } - - return false; -} - -void VMainWindow::openFiles(const QStringList &p_files, - bool p_forceOrphan, - OpenFileMode p_mode, - bool p_forceMode) -{ - for (int i = 0; i < p_files.size(); ++i) { - VFile *file = NULL; - if (!p_forceOrphan) { - file = vnote->getInternalFile(p_files[i]); - } - - if (!file) { - file = vnote->getOrphanFile(p_files[i], true); - } - - editArea->openFile(file, p_mode, p_forceMode); - } -} - -void VMainWindow::editOrphanFileInfo(VFile *p_file) -{ - VOrphanFile *file = dynamic_cast(p_file); - Q_ASSERT(file); - - VOrphanFileInfoDialog dialog(file, this); - if (dialog.exec() == QDialog::Accepted) { - QString imgFolder = dialog.getImageFolder(); - file->setImageFolder(imgFolder); - } -} - -void VMainWindow::checkSharedMemory() -{ - QStringList files = m_guard->fetchFilesToOpen(); - if (!files.isEmpty()) { - qDebug() << "shared memory fetch files" << files; - openFiles(files); - - // Eliminate the signal. - m_guard->fetchAskedToShow(); - - showMainWindow(); - } else if (m_guard->fetchAskedToShow()) { - qDebug() << "shared memory asked to show up"; - showMainWindow(); - } -} - -void VMainWindow::initTrayIcon() -{ - QMenu *menu = new QMenu(this); - QAction *showMainWindowAct = menu->addAction(tr("Show VNote")); - connect(showMainWindowAct, &QAction::triggered, - this, &VMainWindow::showMainWindow); - - QAction *exitAct = menu->addAction(tr("Quit")); - connect(exitAct, &QAction::triggered, - this, &VMainWindow::quitApp); - - m_trayIcon = new QSystemTrayIcon(QIcon(":/resources/icons/32x32/vnote.png"), this); - m_trayIcon->setToolTip(tr("VNote")); - m_trayIcon->setContextMenu(menu); - - connect(m_trayIcon, &QSystemTrayIcon::activated, - this, [this](QSystemTrayIcon::ActivationReason p_reason){ - if (p_reason == QSystemTrayIcon::Trigger) { - this->showMainWindow(); - } - }); - - m_trayIcon->show(); -} - -void VMainWindow::changeEvent(QEvent *p_event) -{ - if (p_event->type() == QEvent::WindowStateChange) { - QWindowStateChangeEvent *eve = dynamic_cast(p_event); - m_windowOldState = eve->oldState(); - } - - QMainWindow::changeEvent(p_event); -} - -void VMainWindow::showMainWindow() -{ - if (this->isMinimized()) { - if (m_windowOldState & Qt::WindowMaximized) { - this->showMaximized(); - } else if (m_windowOldState & Qt::WindowFullScreen) { - this->showFullScreen(); - } else { - this->showNormal(); - } - } else { - this->show(); - // Need to call raise() in macOS. - this->raise(); - } - - this->activateWindow(); -} - -void VMainWindow::openStartupPages() -{ - StartupPageType type = g_config->getStartupPageType(); - switch (type) { - case StartupPageType::ContinueLeftOff: - { - QVector files = g_config->getLastOpenedFiles(); - qDebug() << "open" << files.size() << "last opened files"; - editArea->openFiles(files); - break; - } - - case StartupPageType::SpecificPages: - { - QStringList pagesToOpen = VUtils::filterFilePathsToOpen(g_config->getStartupPages()); - qDebug() << "open startup pages" << pagesToOpen; - openFiles(pagesToOpen); - break; - } - - default: - break; - } -} - -bool VMainWindow::isHeadingSequenceApplicable() const -{ - if (!m_curTab) { - return false; - } - - Q_ASSERT(m_curFile); - - if (!m_curFile->isModifiable() - || m_curFile->getDocType() != DocType::Markdown) { - return false; - } - - return true; -} - -// Popup the attachment list if it is enabled. -bool VMainWindow::showAttachmentListByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - if (obj->m_attachmentBtn->isEnabled()) { - obj->m_attachmentBtn->showPopupWidget(); - } - - return true; -} - -bool VMainWindow::locateCurrentFileByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - if (obj->m_curFile) { - if (obj->locateFile(obj->m_curFile)) { - return false; - } - } - - return true; -} - -bool VMainWindow::toggleExpandModeByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - obj->expandViewAct->trigger(); - return true; -} - -bool VMainWindow::toggleOnePanelViewByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - if (obj->m_panelViewState == PanelViewState::TwoPanels) { - obj->onePanelView(); - } else { - obj->twoPanelView(); - } - - return true; -} - -bool VMainWindow::discardAndReadByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - if (obj->m_curTab) { - obj->discardExitAct->trigger(); - obj->m_curTab->setFocus(); - - return false; - } - - return true; -} - -bool VMainWindow::toggleToolsDockByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - obj->toolDock->setVisible(!obj->toolDock->isVisible()); - return true; -} - -bool VMainWindow::closeFileByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - obj->closeCurrentFile(); - - QWidget *nextFocus = obj->editArea->getCurrentTab(); - if (nextFocus) { - nextFocus->setFocus(); - } else { - obj->m_fileList->setFocus(); - } - - return false; -} - -bool VMainWindow::shortcutsHelpByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - obj->shortcutsHelp(); - return false; -} - -bool VMainWindow::flushLogFileByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_target); - Q_UNUSED(p_data); - -#if defined(QT_NO_DEBUG) - // Flush g_logFile. - g_logFile.flush(); -#endif - - return true; -} - -void VMainWindow::promptNewNotebookIfEmpty() -{ - if (vnote->getNotebooks().isEmpty()) { - notebookSelector->newNotebook(); - } -} - -void VMainWindow::initShortcuts() -{ - QString keySeq = g_config->getShortcutKeySequence("CloseNote"); - qDebug() << "set CloseNote shortcut to" << keySeq; - if (!keySeq.isEmpty()) { - QShortcut *closeNoteShortcut = new QShortcut(QKeySequence(keySeq), this); - closeNoteShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(closeNoteShortcut, &QShortcut::activated, - this, &VMainWindow::closeCurrentFile); - } -} - -void VMainWindow::openFlashPage() -{ - openFiles(QStringList() << g_config->getFlashPage(), - false, - OpenFileMode::Edit, - true); -} - -void VMainWindow::initHeadingButton(QToolBar *p_tb) -{ - m_headingBtn = new QPushButton(VIconUtils::toolButtonIcon(":/resources/icons/heading.svg"), - "", - this); - m_headingBtn->setToolTip(tr("Headings")); - m_headingBtn->setProperty("CornerBtn", true); - m_headingBtn->setFocusPolicy(Qt::NoFocus); - m_headingBtn->setEnabled(false); - - QMenu *menu = new QMenu(this); - QString text(tr("Heading %1")); - QString tooltip(tr("Heading %1\t%2")); - QWidgetAction *wact = new QWidgetAction(menu); - wact->setData(1); - VButtonMenuItem *w = new VButtonMenuItem(wact, text.arg(1), this); - w->setToolTip(tooltip.arg(1).arg(VUtils::getShortcutText("Ctrl+1"))); - w->setProperty("Heading1", true); - wact->setDefaultWidget(w); - menu->addAction(wact); - - wact = new QWidgetAction(menu); - wact->setData(2); - w = new VButtonMenuItem(wact, text.arg(2), this); - w->setToolTip(tooltip.arg(2).arg(VUtils::getShortcutText("Ctrl+2"))); - w->setProperty("Heading2", true); - wact->setDefaultWidget(w); - menu->addAction(wact); - - wact = new QWidgetAction(menu); - wact->setData(3); - w = new VButtonMenuItem(wact, text.arg(3), this); - w->setToolTip(tooltip.arg(3).arg(VUtils::getShortcutText("Ctrl+3"))); - w->setProperty("Heading3", true); - wact->setDefaultWidget(w); - menu->addAction(wact); - - wact = new QWidgetAction(menu); - wact->setData(4); - w = new VButtonMenuItem(wact, text.arg(4), this); - w->setToolTip(tooltip.arg(4).arg(VUtils::getShortcutText("Ctrl+4"))); - w->setProperty("Heading4", true); - wact->setDefaultWidget(w); - menu->addAction(wact); - - wact = new QWidgetAction(menu); - wact->setData(5); - w = new VButtonMenuItem(wact, text.arg(5), this); - w->setToolTip(tooltip.arg(5).arg(VUtils::getShortcutText("Ctrl+5"))); - w->setProperty("Heading5", true); - wact->setDefaultWidget(w); - menu->addAction(wact); - - wact = new QWidgetAction(menu); - wact->setData(6); - w = new VButtonMenuItem(wact, text.arg(6), this); - w->setToolTip(tooltip.arg(6).arg(VUtils::getShortcutText("Ctrl+6"))); - w->setProperty("Heading6", true); - wact->setDefaultWidget(w); - menu->addAction(wact); - - wact = new QWidgetAction(menu); - wact->setData(0); - w = new VButtonMenuItem(wact, tr("Clear"), this); - w->setToolTip(tr("Clear\t%1").arg(VUtils::getShortcutText("Ctrl+7"))); - wact->setDefaultWidget(w); - menu->addAction(wact); - - connect(menu, &QMenu::triggered, - this, [this, menu](QAction *p_action) { - if (m_curTab) { - int level = p_action->data().toInt(); - m_curTab->decorateText(TextDecoration::Heading, level); - } - - menu->hide(); - }); - - m_headingBtn->setMenu(menu); - p_tb->addWidget(m_headingBtn); -} - -void VMainWindow::initThemeMenu(QMenu *p_menu) -{ - QMenu *themeMenu = p_menu->addMenu(tr("Theme")); - themeMenu->setToolTipsVisible(true); - - QActionGroup *ag = new QActionGroup(this); - connect(ag, &QActionGroup::triggered, - this, [this](QAction *p_action) { - if (!p_action) { - return; - } - - QString data = p_action->data().toString(); - g_config->setTheme(data); - }); - - QList themes = g_config->getThemes(); - QString theme = g_config->getTheme(); - for (auto const &item : themes) { - QAction *act = new QAction(item, ag); - act->setToolTip(tr("Set as the theme of VNote (restart VNote to make it work)")); - act->setCheckable(true); - act->setData(item); - - // Add it to the menu. - themeMenu->addAction(act); - - if (theme == item) { - act->setChecked(true); - } - } -} diff --git a/src/vmainwindow.h b/src/vmainwindow.h deleted file mode 100644 index d65ab430..00000000 --- a/src/vmainwindow.h +++ /dev/null @@ -1,413 +0,0 @@ -#ifndef VMAINWINDOW_H -#define VMAINWINDOW_H - -#include -#include -#include -#include -#include -#include "vfile.h" -#include "vedittab.h" - -class QLabel; -class QComboBox; -class VDirectoryTree; -class QSplitter; -class QListWidget; -class QTabWidget; -class QToolBar; -class VNote; -class QAction; -class QPushButton; -class VNotebook; -class QActionGroup; -class VFileList; -class VEditArea; -class VToolBox; -class VOutline; -class VNotebookSelector; -class VAvatar; -class VFindReplaceDialog; -class VCaptain; -class VVimIndicator; -class VTabIndicator; -class VSingleInstanceGuard; -class QTimer; -class QSystemTrayIcon; -class VButtonWithWidget; -class VAttachmentList; -class VSnippetList; - -enum class PanelViewState -{ - ExpandMode, - SinglePanel, - TwoPanels, - CompactMode, - Invalid -}; - -class VMainWindow : public QMainWindow -{ - Q_OBJECT - -public: - VMainWindow(VSingleInstanceGuard *p_guard, QWidget *p_parent = 0); - - // Returns true if the location succeeds. - bool locateFile(VFile *p_file); - - VFileList *getFileList() const; - - VEditArea *getEditArea() const; - - VSnippetList *getSnippetList() const; - - // View and edit the information of @p_file, which is an orphan file. - void editOrphanFileInfo(VFile *p_file); - - // Open files @p_files as orphan files or internal note files. - // If @p_forceOrphan is false, for each file, VNote will try to find out if - // it is a note inside VNote. If yes, VNote will open it as internal file. - void openFiles(const QStringList &p_files, - bool p_forceOrphan = false, - OpenFileMode p_mode = OpenFileMode::Read, - bool p_forceMode = false); - - // Try to open @p_filePath as internal note. - bool tryOpenInternalFile(const QString &p_filePath); - - // Show a temporary message in status bar. - void showStatusMessage(const QString &p_msg); - - // Open startup pages according to configuration. - void openStartupPages(); - - VCaptain *getCaptain() const; - - // Prompt user for new notebook if there is no notebook. - void promptNewNotebookIfEmpty(); - - VFile *getCurrentFile() const; - - VEditTab *getCurrentTab() const; - -signals: - // Emit when editor related configurations were changed by user. - void editorConfigUpdated(); - -private slots: - void importNoteFromFile(); - void viewSettings(); - void changeMarkdownConverter(QAction *action); - void aboutMessage(); - - // Display shortcuts help. - void shortcutsHelp(); - - void changeExpandTab(bool checked); - void setTabStopWidth(QAction *action); - void setEditorBackgroundColor(QAction *action); - void setRenderBackgroundColor(QAction *action); - - void changeHighlightCursorLine(bool p_checked); - void changeHighlightSelectedWord(bool p_checked); - void changeHighlightSearchedWord(bool p_checked); - void changeHighlightTrailingSapce(bool p_checked); - void onePanelView(); - void twoPanelView(); - void compactModeView(); - void curEditFileInfo(); - void deleteCurNote(); - void handleCurrentDirectoryChanged(const VDirectory *p_dir); - void handleCurrentNotebookChanged(const VNotebook *p_notebook); - void handleFindDialogTextChanged(const QString &p_text, uint p_options); - void openFindDialog(); - void enableMermaid(bool p_checked); - void enableMathjax(bool p_checked); - void changeAutoIndent(bool p_checked); - void changeAutoList(bool p_checked); - void changeVimMode(bool p_checked); - void enableCodeBlockHighlight(bool p_checked); - void enableImagePreview(bool p_checked); - void enableImagePreviewConstraint(bool p_checked); - void enableImageConstraint(bool p_checked); - void enableImageCaption(bool p_checked); - void printNote(); - void exportAsPDF(); - - // Set the panel view properly. - void enableCompactMode(bool p_enabled); - - // Handle Vim status updated. - void handleVimStatusUpdated(const VVim *p_vim); - - // Handle the status update of the current tab of VEditArea. - // Will be called frequently. - void handleAreaTabStatusUpdated(const VEditTabInfo &p_info); - - // Check the shared memory between different instances to see if we have - // files to open. - void checkSharedMemory(); - - void quitApp(); - - // Restore main window. - void showMainWindow(); - - // Close current note. - void closeCurrentFile(); - - // Open flash page in edit mode. - void openFlashPage(); - -protected: - void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; - void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; - void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; - - void changeEvent(QEvent *p_event) Q_DECL_OVERRIDE; - -private: - void setupUI(); - QWidget *setupDirectoryPanel(); - - void initToolBar(); - void initFileToolBar(QSize p_iconSize = QSize()); - void initViewToolBar(QSize p_iconSize = QSize()); - - void initNoteToolBar(QSize p_iconSize = QSize()); - - // Init the Edit toolbar. - void initEditToolBar(QSize p_iconSize = QSize()); - - void initMenuBar(); - void initFileMenu(); - void initEditMenu(); - void initViewMenu(); - void initMarkdownMenu(); - void initHelpMenu(); - - void initDockWindows(); - void initAvatar(); - void initPredefinedColorPixmaps(); - void initRenderBackgroundMenu(QMenu *menu); - - void initRenderStyleMenu(QMenu *p_menu); - - void initCodeBlockStyleMenu(QMenu *p_menu); - - void initConverterMenu(QMenu *p_menu); - void initMarkdownitOptionMenu(QMenu *p_menu); - void initEditorBackgroundMenu(QMenu *menu); - - // Init the Line Number submenu in Edit menu. - void initEditorLineNumberMenu(QMenu *p_menu); - - void initEditorStyleMenu(QMenu *p_emnu); - void updateWindowTitle(const QString &str); - - // Update state of actions according to @p_tab. - void updateActionsStateFromTab(const VEditTab *p_tab); - - void saveStateAndGeometry(); - void restoreStateAndGeometry(); - void repositionAvatar(); - - // Should init VCaptain before setupUI(). - void initCaptain(); - - void registerCaptainAndNavigationTargets(); - - // Update status bar information. - void updateStatusInfo(const VEditTabInfo &p_info); - - // Wrapper to create a QAction. - QAction *newAction(const QIcon &p_icon, - const QString &p_text, - QObject *p_parent = nullptr); - - // Init a timer to watch the change of the shared memory between instances of - // VNote. - void initSharedMemoryWatcher(); - - // Init system tray icon and correspondign context menu. - void initTrayIcon(); - - // Change the panel view according to @p_state. - // Will not change m_panelViewState. - void changePanelView(PanelViewState p_state); - - // Whether heading sequence is applicable to current tab. - // Only available for writable Markdown file. - bool isHeadingSequenceApplicable() const; - - void initShortcuts(); - - void initHeadingButton(QToolBar *p_tb); - - void initThemeMenu(QMenu *p_emnu); - - // Captain mode functions. - - // Popup the attachment list if it is enabled. - static bool showAttachmentListByCaptain(void *p_target, void *p_data); - - static bool locateCurrentFileByCaptain(void *p_target, void *p_data); - - static bool toggleExpandModeByCaptain(void *p_target, void *p_data); - - static bool toggleOnePanelViewByCaptain(void *p_target, void *p_data); - - static bool discardAndReadByCaptain(void *p_target, void *p_data); - - static bool toggleToolsDockByCaptain(void *p_target, void *p_data); - - static bool closeFileByCaptain(void *p_target, void *p_data); - - static bool shortcutsHelpByCaptain(void *p_target, void *p_data); - - static bool flushLogFileByCaptain(void *p_target, void *p_data); - - // End Captain mode functions. - - VNote *vnote; - QPointer m_curFile; - QPointer m_curTab; - - VCaptain *m_captain; - - QLabel *notebookLabel; - QLabel *directoryLabel; - VNotebookSelector *notebookSelector; - VFileList *m_fileList; - VDirectoryTree *directoryTree; - - // Splitter for directory | files | edit. - QSplitter *m_mainSplitter; - - // Splitter for directory | files. - // Move directory and file panel in one compact vertical split. - QSplitter *m_naviSplitter; - - VEditArea *editArea; - - QDockWidget *toolDock; - - // Tool box in the dock widget. - VToolBox *m_toolBox; - - VOutline *outline; - - // View and manage snippets. - VSnippetList *m_snippetList; - - VAvatar *m_avatar; - VFindReplaceDialog *m_findReplaceDialog; - VVimIndicator *m_vimIndicator; - VTabIndicator *m_tabIndicator; - - // SinglePanel, TwoPanels, CompactMode. - PanelViewState m_panelViewState; - - // Actions - QAction *newRootDirAct; - QAction *newNoteAct; - QAction *noteInfoAct; - QAction *deleteNoteAct; - QAction *editNoteAct; - QAction *saveNoteAct; - QAction *saveExitAct; - QAction *discardExitAct; - QAction *expandViewAct; - QAction *m_importNoteAct; - QAction *m_printAct; - QAction *m_exportAsPDFAct; - - QAction *m_findReplaceAct; - QAction *m_findNextAct; - QAction *m_findPreviousAct; - QAction *m_replaceAct; - QAction *m_replaceFindAct; - QAction *m_replaceAllAct; - - QAction *m_autoIndentAct; - - // Enable heading sequence for current note. - QAction *m_headingSequenceAct; - - // Act group for render styles. - QActionGroup *m_renderStyleActs; - - // Act group for code block render styles. - QActionGroup *m_codeBlockStyleActs; - - // Act group for panel view actions. - QActionGroup *m_viewActGroup; - - // Menus - QMenu *viewMenu; - - // Edit Toolbar. - QToolBar *m_editToolBar; - - // Attachment button. - VButtonWithWidget *m_attachmentBtn; - - // Attachment list. - VAttachmentList *m_attachmentList; - - QPushButton *m_headingBtn; - - QVector predefinedColorPixmaps; - - // Single instance guard. - VSingleInstanceGuard *m_guard; - - // Timer to check the shared memory between instances of VNote. - QTimer *m_sharedMemTimer; - - // Tray icon. - QSystemTrayIcon *m_trayIcon; - - // The old state of window. - Qt::WindowStates m_windowOldState; - - // Whether user request VNote to quit. - bool m_requestQuit; - - // Interval of the shared memory timer in ms. - static const int c_sharedMemTimerInterval; -}; - -inline VFileList *VMainWindow::getFileList() const -{ - return m_fileList; -} - -inline VEditArea *VMainWindow::getEditArea() const -{ - return editArea; -} - -inline VCaptain *VMainWindow::getCaptain() const -{ - return m_captain; -} - -inline VFile *VMainWindow::getCurrentFile() const -{ - return m_curFile; -} - -inline VEditTab *VMainWindow::getCurrentTab() const -{ - return m_curTab; -} - -inline VSnippetList *VMainWindow::getSnippetList() const -{ - return m_snippetList; -} - -#endif // VMAINWINDOW_H diff --git a/src/vmarkdownconverter.cpp b/src/vmarkdownconverter.cpp deleted file mode 100644 index 8d262845..00000000 --- a/src/vmarkdownconverter.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "vmarkdownconverter.h" -#include - -VMarkdownConverter::VMarkdownConverter() -{ - hoedownHtmlFlags = (hoedown_html_flags)0; - nestingLevel = 16; - - htmlRenderer = hoedown_html_renderer_new(hoedownHtmlFlags, nestingLevel); - tocRenderer = hoedown_html_toc_renderer_new(nestingLevel); -} - -VMarkdownConverter::~VMarkdownConverter() -{ - if (htmlRenderer) { - hoedown_html_renderer_free(htmlRenderer); - } - if (tocRenderer) { - hoedown_html_renderer_free(tocRenderer); - } -} - -QString VMarkdownConverter::generateHtml(const QString &markdown, hoedown_extensions options) -{ - if (markdown.isEmpty()) { - return QString(); - } - hoedown_document *document = hoedown_document_new(htmlRenderer, options, - nestingLevel); - QByteArray data = markdown.toUtf8(); - hoedown_buffer *outBuf = hoedown_buffer_new(data.size()); - hoedown_document_render(document, outBuf, (const uint8_t *)data.constData(), data.size()); - hoedown_document_free(document); - QString html = QString::fromUtf8(hoedown_buffer_cstr(outBuf)); - hoedown_buffer_free(outBuf); - - return html; -} - -QString VMarkdownConverter::generateHtml(const QString &markdown, hoedown_extensions options, QString &toc) -{ - if (markdown.isEmpty()) { - return QString(); - } - - QString html = generateHtml(markdown, options); - QRegularExpression tocExp("

    \\[TOC\\]<\\/p>", QRegularExpression::CaseInsensitiveOption); - toc = generateToc(markdown, options); - html.replace(tocExp, toc); - - return html; -} - -static void processToc(QString &p_toc) -{ - // Hoedown will add '\n'. - p_toc.replace("\n", ""); - // Hoedown will translate `_` in title to ``. - p_toc.replace("", "_"); - p_toc.replace("", "_"); -} - -QString VMarkdownConverter::generateToc(const QString &markdown, hoedown_extensions options) -{ - if (markdown.isEmpty()) { - return QString(); - } - - hoedown_document *document = hoedown_document_new(tocRenderer, options, nestingLevel); - QByteArray data = markdown.toUtf8(); - hoedown_buffer *outBuf = hoedown_buffer_new(16); - hoedown_document_render(document, outBuf, (const uint8_t *)data.constData(), data.size()); - hoedown_document_free(document); - QString toc = QString::fromUtf8(hoedown_buffer_cstr(outBuf)); - hoedown_buffer_free(outBuf); - - processToc(toc); - - return toc; -} diff --git a/src/vmarkdownconverter.h b/src/vmarkdownconverter.h deleted file mode 100644 index cdadfe25..00000000 --- a/src/vmarkdownconverter.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef VMARKDOWNCONVERTER_H -#define VMARKDOWNCONVERTER_H - -#include - -extern "C" { -#include -#include -} - -class VMarkdownConverter -{ -public: - VMarkdownConverter(); - ~VMarkdownConverter(); - - QString generateHtml(const QString &markdown, hoedown_extensions options, QString &toc); - - QString generateToc(const QString &markdown, hoedown_extensions options); - -private: - QString generateHtml(const QString &markdown, hoedown_extensions options); - - // VMarkdownDocument *generateDocument(const QString &markdown); - hoedown_html_flags hoedownHtmlFlags; - int nestingLevel; - hoedown_renderer *htmlRenderer; - hoedown_renderer *tocRenderer; -}; - -#endif // VMARKDOWNCONVERTER_H diff --git a/src/vmdedit.cpp b/src/vmdedit.cpp deleted file mode 100644 index 74a9e0f6..00000000 --- a/src/vmdedit.cpp +++ /dev/null @@ -1,836 +0,0 @@ -#include -#include "vmdedit.h" -#include "hgmarkdownhighlighter.h" -#include "vcodeblockhighlighthelper.h" -#include "vmdeditoperations.h" -#include "vnote.h" -#include "vconfigmanager.h" -#include "vtableofcontent.h" -#include "utils/vutils.h" -#include "utils/veditutils.h" -#include "utils/vpreviewutils.h" -#include "dialog/vselectdialog.h" -#include "dialog/vconfirmdeletiondialog.h" -#include "vtextblockdata.h" -#include "vorphanfile.h" - -extern VConfigManager *g_config; -extern VNote *g_vnote; - -const int VMdEdit::c_numberOfAysncJobs = 2; - -VMdEdit::VMdEdit(VFile *p_file, VDocument *p_vdoc, MarkdownConverterType p_type, - QWidget *p_parent) - : VEdit(p_file, p_parent), m_mdHighlighter(NULL), m_freshEdit(true), - m_finishedAsyncJobs(c_numberOfAysncJobs) -{ - V_ASSERT(p_file->getDocType() == DocType::Markdown); - - setAcceptRichText(false); - - m_mdHighlighter = new HGMarkdownHighlighter(g_config->getMdHighlightingStyles(), - g_config->getCodeBlockStyles(), - g_config->getMarkdownHighlightInterval(), - document()); - - connect(m_mdHighlighter, &HGMarkdownHighlighter::headersUpdated, - this, &VMdEdit::updateHeaders); - - // After highlight, the cursor may trun into non-visible. We should make it visible - // in this case. - connect(m_mdHighlighter, &HGMarkdownHighlighter::highlightCompleted, - this, [this]() { - makeBlockVisible(textCursor().block()); - }); - - m_cbHighlighter = new VCodeBlockHighlightHelper(m_mdHighlighter, p_vdoc, - p_type); - - /* - m_imagePreviewer = new VImagePreviewer(this, m_mdHighlighter); - connect(m_mdHighlighter, &HGMarkdownHighlighter::imageLinksUpdated, - m_imagePreviewer, &VImagePreviewer::imageLinksChanged); - connect(m_imagePreviewer, &VImagePreviewer::requestUpdateImageLinks, - m_mdHighlighter, &HGMarkdownHighlighter::updateHighlight); - connect(m_imagePreviewer, &VImagePreviewer::previewFinished, - this, [this](){ - if (m_freshEdit) { - finishOneAsyncJob(0); - } - }); - - connect(m_imagePreviewer, &VImagePreviewer::previewWidthUpdated, - this, [this](){ - if (m_freshEdit) { - finishOneAsyncJob(1); - } - }); - */ - - // Comment out these lines since we use VMdEditor to replace VMdEdit. - /* - m_editOps = new VMdEditOperations(this, m_file); - - connect(m_editOps, &VEditOperations::statusMessage, - this, &VEdit::statusMessage); - connect(m_editOps, &VEditOperations::vimStatusUpdated, - this, &VEdit::vimStatusUpdated); - - connect(this, &VMdEdit::cursorPositionChanged, - this, &VMdEdit::updateCurrentHeader); - - connect(QApplication::clipboard(), &QClipboard::changed, - this, &VMdEdit::handleClipboardChanged); - */ - - updateFontAndPalette(); - - updateConfig(); -} - -void VMdEdit::updateFontAndPalette() -{ - setFont(g_config->getMdEditFont()); - setPalette(g_config->getMdEditPalette()); -} - -void VMdEdit::beginEdit() -{ - updateFontAndPalette(); - - updateConfig(); - - Q_ASSERT(m_file->getContent() == toPlainTextWithoutImg()); - - initInitImages(); - - setModified(false); - - if (m_freshEdit) { - // Will set to false when all async jobs completed. - setReadOnlyAndHighlight(true); - // Disable and clear undo stacks temporary. - setUndoRedoEnabled(false); - } else { - setReadOnlyAndHighlight(false); - } - - updateHeaders(m_mdHighlighter->getHeaderRegions()); -} - -void VMdEdit::endEdit() -{ - setReadOnlyAndHighlight(true); - clearUnusedImages(); -} - -void VMdEdit::saveFile() -{ - Q_ASSERT(m_file->isModifiable()); - - if (!document()->isModified()) { - return; - } - - m_file->setContent(toPlainTextWithoutImg()); - setModified(false); -} - -void VMdEdit::reloadFile() -{ - const QString &content = m_file->getContent(); - Q_ASSERT(content.indexOf(QChar::ObjectReplacementCharacter) == -1); - - setPlainText(content); - - setModified(false); -} - -void VMdEdit::keyPressEvent(QKeyEvent *event) -{ - if (m_editOps->handleKeyPressEvent(event)) { - return; - } - VEdit::keyPressEvent(event); -} - -bool VMdEdit::canInsertFromMimeData(const QMimeData *source) const -{ - return source->hasImage() || source->hasUrls() - || VEdit::canInsertFromMimeData(source); -} - -void VMdEdit::insertFromMimeData(const QMimeData *source) -{ - VSelectDialog dialog(tr("Insert From Clipboard"), this); - dialog.addSelection(tr("Insert As Image"), 0); - dialog.addSelection(tr("Insert As Text"), 1); - - if (source->hasImage()) { - // Image data in the clipboard - if (source->hasText()) { - if (dialog.exec() == QDialog::Accepted) { - if (dialog.getSelection() == 1) { - // Insert as text. - Q_ASSERT(source->hasText() && source->hasImage()); - VEdit::insertFromMimeData(source); - return; - } - } else { - return; - } - } - m_editOps->insertImageFromMimeData(source); - return; - } else if (source->hasUrls()) { - QList urls = source->urls(); - if (urls.size() == 1 && VUtils::isImageURL(urls[0])) { - if (dialog.exec() == QDialog::Accepted) { - // FIXME: After calling dialog.exec(), source->hasUrl() returns false. - if (dialog.getSelection() == 0) { - // Insert as image. - m_editOps->insertImageFromURL(urls[0]); - return; - } - QMimeData newSource; - newSource.setUrls(urls); - VEdit::insertFromMimeData(&newSource); - return; - } else { - return; - } - } - } else if (source->hasText()) { - QString text = source->text(); - if (VUtils::isImageURLText(text)) { - // The text is a URL to an image. - if (dialog.exec() == QDialog::Accepted) { - if (dialog.getSelection() == 0) { - // Insert as image. - QUrl url(text); - if (url.isValid()) { - m_editOps->insertImageFromURL(QUrl(text)); - } - return; - } - } else { - return; - } - } - Q_ASSERT(source->hasText()); - } - VEdit::insertFromMimeData(source); -} - -void VMdEdit::imageInserted(const QString &p_path) -{ - ImageLink link; - link.m_path = p_path; - if (m_file->useRelativeImageFolder()) { - link.m_type = ImageLink::LocalRelativeInternal; - } else { - link.m_type = ImageLink::LocalAbsolute; - } - - m_insertedImages.append(link); -} - -void VMdEdit::initInitImages() -{ - m_initImages = VUtils::fetchImagesFromMarkdownFile(m_file, - ImageLink::LocalRelativeInternal); -} - -void VMdEdit::clearUnusedImages() -{ - QVector images = VUtils::fetchImagesFromMarkdownFile(m_file, - ImageLink::LocalRelativeInternal); - - QVector unusedImages; - - if (!m_insertedImages.isEmpty()) { - for (int i = 0; i < m_insertedImages.size(); ++i) { - const ImageLink &link = m_insertedImages[i]; - - if (link.m_type != ImageLink::LocalRelativeInternal) { - continue; - } - - int j; - for (j = 0; j < images.size(); ++j) { - if (VUtils::equalPath(link.m_path, images[j].m_path)) { - break; - } - } - - // This inserted image is no longer in the file. - if (j == images.size()) { - unusedImages.push_back(link.m_path); - } - } - - m_insertedImages.clear(); - } - - for (int i = 0; i < m_initImages.size(); ++i) { - const ImageLink &link = m_initImages[i]; - - V_ASSERT(link.m_type == ImageLink::LocalRelativeInternal); - - int j; - for (j = 0; j < images.size(); ++j) { - if (VUtils::equalPath(link.m_path, images[j].m_path)) { - break; - } - } - - // Original local relative image is no longer in the file. - if (j == images.size()) { - unusedImages.push_back(link.m_path); - } - } - - if (!unusedImages.isEmpty()) { - if (g_config->getConfirmImagesCleanUp()) { - QVector items; - for (auto const & img : unusedImages) { - items.push_back(ConfirmItemInfo(img, - img, - img, - NULL)); - - } - - QString text = tr("Following images seems not to be used in this note anymore. " - "Please confirm the deletion of these images."); - - QString info = tr("Deleted files could be found in the recycle " - "bin of this note.
    " - "Click \"Cancel\" to leave them untouched."); - - VConfirmDeletionDialog dialog(tr("Confirm Cleaning Up Unused Images"), - text, - info, - items, - true, - true, - true, - this); - - unusedImages.clear(); - if (dialog.exec()) { - items = dialog.getConfirmedItems(); - g_config->setConfirmImagesCleanUp(dialog.getAskAgainEnabled()); - - for (auto const & item : items) { - unusedImages.push_back(item.m_name); - } - } - } - - for (int i = 0; i < unusedImages.size(); ++i) { - bool ret = false; - if (m_file->getType() == FileType::Note) { - const VNoteFile *tmpFile = dynamic_cast((VFile *)m_file); - ret = VUtils::deleteFile(tmpFile->getNotebook(), unusedImages[i], false); - } else if (m_file->getType() == FileType::Orphan) { - const VOrphanFile *tmpFile = dynamic_cast((VFile *)m_file); - ret = VUtils::deleteFile(tmpFile, unusedImages[i], false); - } else { - Q_ASSERT(false); - } - - if (!ret) { - qWarning() << "fail to delete unused original image" << unusedImages[i]; - } else { - qDebug() << "delete unused image" << unusedImages[i]; - } - } - } - - m_initImages.clear(); -} - -void VMdEdit::updateCurrentHeader() -{ - emit currentHeaderChanged(textCursor().block().blockNumber()); -} - -static void addHeaderSequence(QVector &p_sequence, int p_level, int p_baseLevel) -{ - Q_ASSERT(p_level >= 1 && p_level < p_sequence.size()); - if (p_level < p_baseLevel) { - p_sequence.fill(0); - return; - } - - ++p_sequence[p_level]; - for (int i = p_level + 1; i < p_sequence.size(); ++i) { - p_sequence[i] = 0; - } -} - -static QString headerSequenceStr(const QVector &p_sequence) -{ - QString res; - for (int i = 1; i < p_sequence.size(); ++i) { - if (p_sequence[i] != 0) { - res = res + QString::number(p_sequence[i]) + '.'; - } else if (res.isEmpty()) { - continue; - } else { - break; - } - } - - return res; -} - -static void insertSequenceToHeader(QTextBlock p_block, - QRegExp &p_reg, - QRegExp &p_preReg, - const QString &p_seq) -{ - if (!p_block.isValid()) { - return; - } - - QString text = p_block.text(); - bool matched = p_reg.exactMatch(text); - Q_ASSERT(matched); - - matched = p_preReg.exactMatch(text); - Q_ASSERT(matched); - - int start = p_reg.cap(1).length() + 1; - int end = p_preReg.cap(1).length(); - - Q_ASSERT(start <= end); - - QTextCursor cursor(p_block); - cursor.setPosition(p_block.position() + start); - if (start != end) { - cursor.setPosition(p_block.position() + end, QTextCursor::KeepAnchor); - } - - if (p_seq.isEmpty()) { - cursor.removeSelectedText(); - } else { - cursor.insertText(p_seq + ' '); - } -} - -void VMdEdit::updateHeaders(const QVector &p_headerRegions) -{ - QTextDocument *doc = document(); - - QVector headers; - QVector headerBlockNumbers; - QVector headerSequences; - if (!p_headerRegions.isEmpty()) { - headers.reserve(p_headerRegions.size()); - headerBlockNumbers.reserve(p_headerRegions.size()); - headerSequences.reserve(p_headerRegions.size()); - } - - // Assume that each block contains only one line - // Only support # syntax for now - QRegExp headerReg(VUtils::c_headerRegExp); - int baseLevel = -1; - for (auto const & reg : p_headerRegions) { - QTextBlock block = doc->findBlock(reg.m_startPos); - if (!block.isValid()) { - continue; - } - - Q_ASSERT(block.lineCount() == 1); - - if (!block.contains(reg.m_endPos - 1)) { - continue; - } - - if ((block.userState() == HighlightBlockState::Normal) && - headerReg.exactMatch(block.text())) { - int level = headerReg.cap(1).length(); - VTableOfContentItem header(headerReg.cap(2).trimmed(), - level, - block.blockNumber(), - headers.size()); - headers.append(header); - headerBlockNumbers.append(block.blockNumber()); - headerSequences.append(headerReg.cap(3)); - - if (baseLevel == -1) { - baseLevel = level; - } else if (baseLevel > level) { - baseLevel = level; - } - } - } - - m_headers.clear(); - - bool autoSequence = m_config.m_enableHeadingSequence - && !isReadOnly() - && m_file->isModifiable(); - int headingSequenceBaseLevel = g_config->getHeadingSequenceBaseLevel(); - if (headingSequenceBaseLevel < 1 || headingSequenceBaseLevel > 6) { - headingSequenceBaseLevel = 1; - } - - QVector seqs(7, 0); - QRegExp preReg(VUtils::c_headerPrefixRegExp); - int curLevel = baseLevel - 1; - for (int i = 0; i < headers.size(); ++i) { - VTableOfContentItem &item = headers[i]; - while (item.m_level > curLevel + 1) { - curLevel += 1; - - // Insert empty level which is an invalid header. - m_headers.append(VTableOfContentItem(c_emptyHeaderName, - curLevel, - -1, - m_headers.size())); - if (autoSequence) { - addHeaderSequence(seqs, curLevel, headingSequenceBaseLevel); - } - } - - item.m_index = m_headers.size(); - m_headers.append(item); - curLevel = item.m_level; - if (autoSequence) { - addHeaderSequence(seqs, item.m_level, headingSequenceBaseLevel); - - QString seqStr = headerSequenceStr(seqs); - if (headerSequences[i] != seqStr) { - // Insert correct sequence. - insertSequenceToHeader(doc->findBlockByNumber(headerBlockNumbers[i]), - headerReg, - preReg, - seqStr); - } - } - } - - emit headersChanged(m_headers); - - updateCurrentHeader(); -} - -bool VMdEdit::scrollToHeader(int p_blockNumber) -{ - if (p_blockNumber < 0) { - return false; - } - - return scrollToBlock(p_blockNumber); -} - -QString VMdEdit::toPlainTextWithoutImg() -{ - QString text; - bool readOnly = isReadOnly(); - setReadOnlyAndHighlight(true); - text = getPlainTextWithoutPreviewImage(); - setReadOnlyAndHighlight(readOnly); - - return text; -} - -QString VMdEdit::getPlainTextWithoutPreviewImage() const -{ - QVector deletions; - - while (true) { - deletions.clear(); - - /* - while (m_imagePreviewer->isPreviewing()) { - VUtils::sleepWait(100); - } - */ - - // Iterate all the block to get positions for deletion. - // QTextBlock block = document()->begin(); - bool tryAgain = false; - /* - while (block.isValid()) { - if (VTextBlockData::containsPreviewImage(block)) { - if (!getPreviewImageRegionOfBlock(block, deletions)) { - tryAgain = true; - break; - } - } - - block = block.next(); - } - */ - - if (tryAgain) { - continue; - } - - QString text = toPlainText(); - // deletions is sorted by m_startPos. - // From back to front. - for (int i = deletions.size() - 1; i >= 0; --i) { - const Region ® = deletions[i]; - qDebug() << "img region to delete" << reg.m_startPos << reg.m_endPos; - text.remove(reg.m_startPos, reg.m_endPos - reg.m_startPos); - } - - return text; - } -} - -bool VMdEdit::getPreviewImageRegionOfBlock(const QTextBlock &p_block, - QVector &p_regions) const -{ - QTextDocument *doc = document(); - QVector regs; - QString text = p_block.text(); - int nrOtherChar = 0; - int nrImage = 0; - bool hasBlock = false; - - // From back to front. - for (int i = text.size() - 1; i >= 0; --i) { - if (text[i].isSpace()) { - continue; - } - - if (text[i] == QChar::ObjectReplacementCharacter) { - int pos = p_block.position() + i; - Q_ASSERT(doc->characterAt(pos) == QChar::ObjectReplacementCharacter); - - QTextImageFormat imageFormat = VPreviewUtils::fetchFormatFromPosition(doc, pos); - if (imageFormat.isValid()) { - ++nrImage; - bool isBlock = VPreviewUtils::getPreviewImageType(imageFormat) == PreviewImageType::Block; - if (isBlock) { - hasBlock = true; - } else { - regs.push_back(Region(pos, pos + 1)); - } - } else { - return false; - } - } else { - ++nrOtherChar; - } - } - - if (hasBlock) { - if (nrOtherChar > 0 || nrImage > 1) { - // Inconsistent state. - return false; - } - - regs.push_back(Region(p_block.position(), p_block.position() + p_block.length())); - } - - p_regions.append(regs); - return true; -} - -void VMdEdit::handleClipboardChanged(QClipboard::Mode p_mode) -{ - if (!hasFocus()) { - return; - } - - if (p_mode == QClipboard::Clipboard) { - QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - if (mimeData->hasText()) { - QString text = mimeData->text(); - if (clipboard->ownsClipboard()) { - if (text.trimmed() == QString(QChar::ObjectReplacementCharacter)) { - QImage image = tryGetSelectedImage(); - clipboard->clear(QClipboard::Clipboard); - if (!image.isNull()) { - clipboard->setImage(image, QClipboard::Clipboard); - } - } else { - // Try to remove all the preview image in text. - VEditUtils::removeObjectReplacementCharacter(text); - if (text.size() != mimeData->text().size()) { - clipboard->clear(QClipboard::Clipboard); - clipboard->setText(text); - } - } - } - } - } -} - -QImage VMdEdit::tryGetSelectedImage() -{ - QImage image; - QTextCursor cursor = textCursor(); - if (!cursor.hasSelection()) { - return image; - } - int start = cursor.selectionStart(); - int end = cursor.selectionEnd(); - QTextDocument *doc = document(); - QTextImageFormat format; - for (int i = start; i < end; ++i) { - if (doc->characterAt(i) == QChar::ObjectReplacementCharacter) { - format = VPreviewUtils::fetchFormatFromPosition(doc, i); - break; - } - } - - if (format.isValid()) { - PreviewImageSource src = VPreviewUtils::getPreviewImageSource(format); - // long long id = VPreviewUtils::getPreviewImageID(format); - if (src == PreviewImageSource::Image) { - /* - Q_ASSERT(m_imagePreviewer->isEnabled()); - image = m_imagePreviewer->fetchCachedImageByID(id); - */ - } - } - - return image; -} - -void VMdEdit::resizeEvent(QResizeEvent *p_event) -{ - /* - m_imagePreviewer->updatePreviewImageWidth(); - */ - - VEdit::resizeEvent(p_event); -} - -int VMdEdit::indexOfCurrentHeader() const -{ - if (m_headers.isEmpty()) { - return -1; - } - - int blockNumber = textCursor().block().blockNumber(); - for (int i = m_headers.size() - 1; i >= 0; --i) { - if (!m_headers[i].isEmpty() - && m_headers[i].m_blockNumber <= blockNumber) { - return i; - } - } - - return -1; -} - -bool VMdEdit::jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat) -{ - if (m_headers.isEmpty()) { - return false; - } - - QTextCursor cursor = textCursor(); - int cursorLine = cursor.block().blockNumber(); - int targetIdx = -1; - // -1: skip level check. - int targetLevel = 0; - int idx = indexOfCurrentHeader(); - if (idx == -1) { - // Cursor locates at the beginning, before any headers. - if (p_relativeLevel < 0 || !p_forward) { - return false; - } - } - - int delta = 1; - if (!p_forward) { - delta = -1; - } - - bool firstHeader = true; - for (targetIdx = idx == -1 ? 0 : idx; - targetIdx >= 0 && targetIdx < m_headers.size(); - targetIdx += delta) { - const VTableOfContentItem &header = m_headers[targetIdx]; - if (header.isEmpty()) { - continue; - } - - if (targetLevel == 0) { - // The target level has not been init yet. - Q_ASSERT(firstHeader); - targetLevel = header.m_level; - if (p_relativeLevel < 0) { - targetLevel += p_relativeLevel; - if (targetLevel < 1) { - // Invalid level. - return false; - } - } else if (p_relativeLevel > 0) { - targetLevel = -1; - } - } - - if (targetLevel == -1 || header.m_level == targetLevel) { - if (firstHeader - && (cursorLine == header.m_blockNumber - || p_forward) - && idx != -1) { - // This header is not counted for the repeat. - firstHeader = false; - continue; - } - - if (--p_repeat == 0) { - // Found. - break; - } - } else if (header.m_level < targetLevel) { - // Stop by higher level. - return false; - } - - firstHeader = false; - } - - if (targetIdx < 0 || targetIdx >= m_headers.size()) { - return false; - } - - // Jump to target header. - int line = m_headers[targetIdx].m_blockNumber; - if (line > -1) { - QTextBlock block = document()->findBlockByNumber(line); - if (block.isValid()) { - cursor.setPosition(block.position()); - setTextCursor(cursor); - return true; - } - } - - return false; -} - -void VMdEdit::finishOneAsyncJob(int p_idx) -{ - Q_ASSERT(m_freshEdit); - if (m_finishedAsyncJobs[p_idx]) { - return; - } - - m_finishedAsyncJobs[p_idx] = true; - if (-1 == m_finishedAsyncJobs.indexOf(false)) { - // All jobs finished. - setUndoRedoEnabled(true); - - setReadOnlyAndHighlight(false); - - setModified(false); - m_freshEdit = false; - emit statusChanged(); - - updateHeaders(m_mdHighlighter->getHeaderRegions()); - - emit ready(); - } -} diff --git a/src/vmdedit.h b/src/vmdedit.h deleted file mode 100644 index 36ab0974..00000000 --- a/src/vmdedit.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef VMDEDIT_H -#define VMDEDIT_H - -#include "vedit.h" -#include -#include -#include -#include -#include -#include "vtableofcontent.h" -#include "veditoperations.h" -#include "vconfigmanager.h" -#include "utils/vutils.h" - -class HGMarkdownHighlighter; -class VCodeBlockHighlightHelper; -class VDocument; - -class VMdEdit : public VEdit -{ - Q_OBJECT -public: - VMdEdit(VFile *p_file, VDocument *p_vdoc, MarkdownConverterType p_type, - QWidget *p_parent = 0); - void beginEdit() Q_DECL_OVERRIDE; - void endEdit() Q_DECL_OVERRIDE; - void saveFile() Q_DECL_OVERRIDE; - void reloadFile() Q_DECL_OVERRIDE; - - // An image has been inserted. The image is relative. - // @p_path is the absolute path of the inserted image. - void imageInserted(const QString &p_path); - - // Scroll to header @p_blockNumber. - // Return true if @p_blockNumber is valid to scroll to. - bool scrollToHeader(int p_blockNumber); - - // Like toPlainText(), but remove image preview characters. - QString toPlainTextWithoutImg(); - -public slots: - bool jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat) Q_DECL_OVERRIDE; - -signals: - // Signal when headers change. - void headersChanged(const QVector &p_headers); - - // Signal when current header change. - void currentHeaderChanged(int p_blockNumber); - - // Signal when the status of VMdEdit changed. - // Will be emitted by VImagePreviewer for now. - void statusChanged(); - -private slots: - // Update m_headers according to elements. - void updateHeaders(const QVector &p_headerRegions); - - // Update current header according to cursor position. - // When there is no header in current cursor, will signal an invalid header. - void updateCurrentHeader(); - - void handleClipboardChanged(QClipboard::Mode p_mode); - -protected: - void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; - bool canInsertFromMimeData(const QMimeData *source) const Q_DECL_OVERRIDE; - void insertFromMimeData(const QMimeData *source) Q_DECL_OVERRIDE; - void updateFontAndPalette() Q_DECL_OVERRIDE; - void resizeEvent(QResizeEvent *p_event) Q_DECL_OVERRIDE; - -private: - struct Region - { - Region() : m_startPos(-1), m_endPos(-1) - { - } - - Region(int p_start, int p_end) - : m_startPos(p_start), m_endPos(p_end) - { - } - - int m_startPos; - int m_endPos; - }; - - // Get the initial images from file before edit. - void initInitImages(); - - // Clear two kind of images according to initial images and current images: - // 1. Newly inserted images which are deleted later; - // 2. Initial images which are deleted; - void clearUnusedImages(); - - // There is a QChar::ObjectReplacementCharacter (and maybe some spaces) - // in the selection. Get the QImage. - QImage tryGetSelectedImage(); - - QString getPlainTextWithoutPreviewImage() const; - - // Try to get all the regions of preview image within @p_block. - // Returns false if preview image is not ready yet. - bool getPreviewImageRegionOfBlock(const QTextBlock &p_block, - QVector &p_regions) const; - - void finishOneAsyncJob(int p_idx); - - // Index in m_headers of current header which contains the cursor. - int indexOfCurrentHeader() const; - - HGMarkdownHighlighter *m_mdHighlighter; - VCodeBlockHighlightHelper *m_cbHighlighter; - // VImagePreviewer *m_imagePreviewer; - - // Image links inserted while editing. - QVector m_insertedImages; - - // Image links right at the beginning of the edit. - QVector m_initImages; - - // Mainly used for title jump. - QVector m_headers; - - bool m_freshEdit; - - QVector m_finishedAsyncJobs; - - static const int c_numberOfAysncJobs; -}; - -#endif // VMDEDIT_H diff --git a/src/vmdeditoperations.cpp b/src/vmdeditoperations.cpp deleted file mode 100644 index 2093f046..00000000 --- a/src/vmdeditoperations.cpp +++ /dev/null @@ -1,1052 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "vmdeditoperations.h" -#include "dialog/vinsertimagedialog.h" -#include "dialog/vselectdialog.h" -#include "utils/vutils.h" -#include "veditor.h" -#include "vdownloader.h" -#include "vfile.h" -#include "vmdeditor.h" -#include "vconfigmanager.h" -#include "utils/vvim.h" -#include "utils/veditutils.h" - -extern VConfigManager *g_config; - -const QString VMdEditOperations::c_defaultImageTitle = ""; - -VMdEditOperations::VMdEditOperations(VEditor *p_editor, VFile *p_file) - : VEditOperations(p_editor, p_file), m_autoIndentPos(-1) -{ -} - -bool VMdEditOperations::insertImageFromMimeData(const QMimeData *source) -{ - QImage image = qvariant_cast(source->imageData()); - if (image.isNull()) { - return false; - } - - VInsertImageDialog dialog(tr("Insert Image From Clipboard"), - c_defaultImageTitle, - "", - false, - m_editor->getEditor()); - dialog.setImage(image); - if (dialog.exec() == QDialog::Accepted) { - insertImageFromQImage(dialog.getImageTitleInput(), - m_file->fetchImageFolderPath(), - m_file->getImageFolderInLink(), - image); - } - - return true; -} - -void VMdEditOperations::insertImageFromQImage(const QString &title, const QString &path, - const QString &folderInLink, const QImage &image) -{ - QString fileName = VUtils::generateImageFileName(path, title); - QString filePath = QDir(path).filePath(fileName); - V_ASSERT(!QFile(filePath).exists()); - - QString errStr; - bool ret = VUtils::makePath(path); - if (!ret) { - errStr = tr("Fail to create image folder %2.") - .arg(g_config->c_dataTextStyle).arg(path); - } else { - ret = image.save(filePath); - if (!ret) { - errStr = tr("Fail to save image %2.") - .arg(g_config->c_dataTextStyle).arg(filePath); - } - } - - if (!ret) { - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Fail to insert image %2.").arg(g_config->c_dataTextStyle).arg(title), - errStr, - QMessageBox::Ok, - QMessageBox::Ok, - m_editor->getEditor()); - return; - } - - QString url = QString("%1/%2").arg(folderInLink).arg(fileName); - QString md = QString("![%1](%2)").arg(title).arg(url); - insertTextAtCurPos(md); - - qDebug() << "insert image" << title << filePath; - - VMdEditor *mdEditor = dynamic_cast(m_editor); - Q_ASSERT(mdEditor); - mdEditor->imageInserted(filePath, url); -} - -void VMdEditOperations::insertImageFromPath(const QString &title, const QString &path, - const QString &folderInLink, const QString &oriImagePath) -{ - QString fileName = VUtils::generateImageFileName(path, title, QFileInfo(oriImagePath).suffix()); - QString filePath = QDir(path).filePath(fileName); - V_ASSERT(!QFile(filePath).exists()); - - QString errStr; - bool ret = VUtils::makePath(path); - if (!ret) { - errStr = tr("Fail to create image folder %2.") - .arg(g_config->c_dataTextStyle).arg(path); - } else { - ret = QFile::copy(oriImagePath, filePath); - if (!ret) { - errStr = tr("Fail to copy image %2.") - .arg(g_config->c_dataTextStyle).arg(filePath); - } - } - - if (!ret) { - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Fail to insert image %2.").arg(g_config->c_dataTextStyle).arg(title), - errStr, - QMessageBox::Ok, - QMessageBox::Ok, - m_editor->getEditor()); - return; - } - - QString url = QString("%1/%2").arg(folderInLink).arg(fileName); - QString md = QString("![%1](%2)").arg(title).arg(url); - insertTextAtCurPos(md); - - qDebug() << "insert image" << title << filePath; - - VMdEditor *mdEditor = dynamic_cast(m_editor); - Q_ASSERT(mdEditor); - mdEditor->imageInserted(filePath, url); -} - -bool VMdEditOperations::insertImageFromURL(const QUrl &imageUrl) -{ - QString imagePath; - QImage image; - bool isLocal = imageUrl.isLocalFile(); - QString title; - - // Whether it is a local file or web URL - if (isLocal) { - imagePath = imageUrl.toLocalFile(); - image = QImage(imagePath); - - if (image.isNull()) { - qWarning() << "image is null"; - return false; - } - title = "Insert Image From File"; - } else { - imagePath = imageUrl.toString(); - title = "Insert Image From Network"; - } - - - VInsertImageDialog dialog(title, - c_defaultImageTitle, - imagePath, - false, - m_editor->getEditor()); - if (isLocal) { - dialog.setImage(image); - } else { - // Download it to a QImage - VDownloader *downloader = new VDownloader(&dialog); - connect(downloader, &VDownloader::downloadFinished, - &dialog, &VInsertImageDialog::imageDownloaded); - downloader->download(imageUrl.toString()); - } - if (dialog.exec() == QDialog::Accepted) { - if (isLocal) { - insertImageFromPath(dialog.getImageTitleInput(), - m_file->fetchImageFolderPath(), - m_file->getImageFolderInLink(), - imagePath); - } else { - insertImageFromQImage(dialog.getImageTitleInput(), - m_file->fetchImageFolderPath(), - m_file->getImageFolderInLink(), - dialog.getImage()); - } - } - return true; -} - -bool VMdEditOperations::insertImage() -{ - // Use empty title and path to let the dialog auto complete. - VInsertImageDialog dialog(tr("Insert Image"), - "", - "", - true, - m_editor->getEditor()); - if (dialog.exec() == QDialog::Accepted) { - VInsertImageDialog::ImageType type = dialog.getImageType(); - if (type == VInsertImageDialog::ImageType::LocalFile) { - insertImageFromPath(dialog.getImageTitleInput(), - m_file->fetchImageFolderPath(), - m_file->getImageFolderInLink(), - dialog.getPathInput()); - } else { - QImage img = dialog.getImage(); - if (!img.isNull()) { - insertImageFromQImage(dialog.getImageTitleInput(), - m_file->fetchImageFolderPath(), - m_file->getImageFolderInLink(), - img); - } - } - } - - return true; -} - -bool VMdEditOperations::handleKeyPressEvent(QKeyEvent *p_event) -{ - if (m_editConfig->m_enableVimMode - && m_vim->handleKeyPressEvent(p_event, &m_autoIndentPos)) { - return true; - } - - bool ret = false; - int key = p_event->key(); - int modifiers = p_event->modifiers(); - - switch (key) { - case Qt::Key_1: - case Qt::Key_2: - case Qt::Key_3: - case Qt::Key_4: - case Qt::Key_5: - case Qt::Key_6: - case Qt::Key_7: - { - if (modifiers == Qt::ControlModifier) { - // Ctrl + : insert title at level . - if (decorateHeading(key == Qt::Key_7 ? 0 : key - Qt::Key_0)) { - p_event->accept(); - ret = true; - goto exit; - } - } - break; - } - - case Qt::Key_Tab: - { - if (handleKeyTab(p_event)) { - ret = true; - goto exit; - } - break; - } - - case Qt::Key_Backtab: - { - if (handleKeyBackTab(p_event)) { - ret = true; - goto exit; - } - break; - } - - case Qt::Key_B: - { - if (modifiers == Qt::ControlModifier) { - decorateBold(); - p_event->accept(); - ret = true; - } - - break; - } - - case Qt::Key_H: - { - if (handleKeyH(p_event)) { - ret = true; - goto exit; - } - break; - } - - case Qt::Key_I: - { - if (modifiers == Qt::ControlModifier) { - decorateItalic(); - p_event->accept(); - ret = true; - } - - break; - } - - case Qt::Key_L: - { - if (modifiers == Qt::ControlModifier) { - m_editor->insertLink(); - p_event->accept(); - ret = true; - } - - break; - } - - case Qt::Key_Apostrophe: - { - if (modifiers == Qt::ControlModifier) { - m_editor->insertImage(); - p_event->accept(); - ret = true; - } - - break; - } - - case Qt::Key_M: - { - if (modifiers == Qt::ControlModifier) { - decorateCodeBlock(); - p_event->accept(); - ret = true; - } - - break; - } - - case Qt::Key_K: - { - if (modifiers == Qt::ControlModifier) { - decorateInlineCode(); - p_event->accept(); - ret = true; - } - - break; - } - - case Qt::Key_U: - { - if (handleKeyU(p_event)) { - ret = true; - goto exit; - } - break; - } - - case Qt::Key_W: - { - if (handleKeyW(p_event)) { - ret = true; - goto exit; - } - break; - } - - case Qt::Key_BracketLeft: - { - if (handleKeyBracketLeft(p_event)) { - ret = true; - goto exit; - } - break; - } - - case Qt::Key_Escape: - { - if (handleKeyEsc(p_event)) { - ret = true; - goto exit; - } - break; - } - - case Qt::Key_Enter: - // Fall through. - case Qt::Key_Return: - { - if (handleKeyReturn(p_event)) { - ret = true; - goto exit; - } - break; - } - - case Qt::Key_D: - { - if (modifiers == Qt::ControlModifier) { - decorateStrikethrough(); - p_event->accept(); - ret = true; - } - - break; - } - - default: - break; - } - -exit: - // Qt::Key_Return, Qt::Key_Tab and Qt::Key_Backtab will handle m_autoIndentPos. - if (key != Qt::Key_Return - && key != Qt::Key_Enter - && key != Qt::Key_Tab - && key != Qt::Key_Backtab - && key != Qt::Key_Shift - && key != Qt::Key_Control) { - m_autoIndentPos = -1; - } - - return ret; -} - -// Let Ctrl+[ behave exactly like ESC. -bool VMdEditOperations::handleKeyBracketLeft(QKeyEvent *p_event) -{ - // 1. If there is any selection, clear it. - // 2. Otherwise, ignore this event and let parent handles it. - if (p_event->modifiers() == Qt::ControlModifier) { - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.hasSelection()) { - cursor.clearSelection(); - m_editor->setTextCursorW(cursor); - p_event->accept(); - return true; - } - } - - return false; -} - -bool VMdEditOperations::handleKeyTab(QKeyEvent *p_event) -{ - QString text(m_editConfig->m_tabSpaces); - - if (p_event->modifiers() == Qt::NoModifier) { - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.hasSelection()) { - m_autoIndentPos = -1; - cursor.beginEditBlock(); - // Indent each selected line. - VEditUtils::indentSelectedBlocks(cursor, text, true); - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); - } else { - // If it is a Tab key following auto list, increase the indent level. - QTextBlock block = cursor.block(); - int seq = -1; - if (m_autoIndentPos == cursor.position() - && VEditUtils::isListBlock(block, &seq)) { - QTextCursor blockCursor(block); - blockCursor.beginEditBlock(); - blockCursor.insertText(text); - if (seq != -1) { - changeListBlockSeqNumber(block, 1); - } - blockCursor.endEditBlock(); - // Change m_autoIndentPos to let it can be repeated. - m_autoIndentPos = m_editor->textCursorW().position(); - } else { - // Just insert "tab". - insertTextAtCurPos(text); - m_autoIndentPos = -1; - } - } - } else { - m_autoIndentPos = -1; - return false; - } - p_event->accept(); - return true; -} - -bool VMdEditOperations::handleKeyBackTab(QKeyEvent *p_event) -{ - if (p_event->modifiers() != Qt::ShiftModifier) { - m_autoIndentPos = -1; - return false; - } - - QTextCursor cursor = m_editor->textCursorW(); - QTextBlock block = m_editor->documentW()->findBlock(cursor.selectionStart()); - bool continueAutoIndent = false; - int seq = -1; - if (cursor.position() == m_autoIndentPos - && VEditUtils::isListBlock(block, &seq) && - !cursor.hasSelection()) { - continueAutoIndent = true; - } - - cursor.beginEditBlock(); - if (continueAutoIndent && seq != -1) { - changeListBlockSeqNumber(block, 1); - } - - VEditUtils::indentSelectedBlocks(cursor, m_editConfig->m_tabSpaces, false); - cursor.endEditBlock(); - - if (continueAutoIndent) { - m_autoIndentPos = m_editor->textCursorW().position(); - } else { - m_autoIndentPos = -1; - } - p_event->accept(); - return true; -} - -bool VMdEditOperations::handleKeyH(QKeyEvent *p_event) -{ - if (p_event->modifiers() == Qt::ControlModifier) { - // Ctrl+H, equal to backspace. - QTextCursor cursor = m_editor->textCursorW(); - cursor.deletePreviousChar(); - - p_event->accept(); - return true; - } - return false; -} - -bool VMdEditOperations::handleKeyU(QKeyEvent *p_event) -{ - if (p_event->modifiers() == Qt::ControlModifier) { - // Ctrl+U, delete till the start of line. - QTextCursor cursor = m_editor->textCursorW(); - bool ret; - if (cursor.atBlockStart()) { - ret = cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); - } else { - ret = cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor); - } - if (ret) { - cursor.removeSelectedText(); - } - - p_event->accept(); - return true; - } - return false; -} - -bool VMdEditOperations::handleKeyW(QKeyEvent *p_event) -{ - if (p_event->modifiers() == Qt::ControlModifier) { - // Ctrl+W, delete till the start of previous word. - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.hasSelection()) { - cursor.removeSelectedText(); - } else { - bool ret = cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); - if (ret) { - cursor.removeSelectedText(); - } - } - p_event->accept(); - return true; - } - return false; -} - -bool VMdEditOperations::handleKeyEsc(QKeyEvent *p_event) -{ - // 1. If there is any selection, clear it. - // 2. Otherwise, ignore this event and let parent handles it. - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.hasSelection()) { - cursor.clearSelection(); - m_editor->setTextCursorW(cursor); - p_event->accept(); - return true; - } - - return false; -} - -bool VMdEditOperations::handleKeyReturn(QKeyEvent *p_event) -{ - bool autolist = true; - if (p_event->modifiers() & Qt::ControlModifier) { - m_autoIndentPos = -1; - return false; - } else if (p_event->modifiers() & Qt::ShiftModifier) { - // Insert two spaces and a new line. - m_autoIndentPos = -1; - - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - cursor.removeSelectedText(); - cursor.insertText(" "); - cursor.endEditBlock(); - - // Let remaining logics handle inserting the new block except that we - // do not need to insert auto list. - autolist = false; - } - - // See if we need to cancel auto indent. - if (m_autoIndentPos > -1) { - // Cancel the auto indent/list if the pos is the same and cursor is at - // the end of a block. - QTextCursor cursor = m_editor->textCursorW(); - if (VEditUtils::needToCancelAutoIndent(m_autoIndentPos, cursor)) { - m_autoIndentPos = -1; - VEditUtils::deleteIndentAndListMark(cursor); - m_editor->setTextCursorW(cursor); - return true; - } - } - - bool handled = false; - m_autoIndentPos = -1; - if (g_config->getAutoIndent()) { - handled = true; - - QTextCursor cursor = m_editor->textCursorW(); - bool textInserted = false; - cursor.beginEditBlock(); - cursor.removeSelectedText(); - - // Indent the new line as previous line. - textInserted = VEditUtils::insertBlockWithIndent(cursor); - - // Continue the list from previous line. - if (g_config->getAutoList() && autolist) { - textInserted = VEditUtils::insertListMarkAsPreviousBlock(cursor) || textInserted; - } - - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); - if (textInserted) { - m_autoIndentPos = m_editor->textCursorW().position(); - } - } - - return handled; -} - -void VMdEditOperations::changeListBlockSeqNumber(QTextBlock &p_block, int p_seq) -{ - QString text = p_block.text(); - QRegExp regExp("^(\\s*)(\\d+)\\.\\s"); - - int idx = regExp.indexIn(text); - if (idx == -1 || regExp.captureCount() != 2) { - return; - } - - int oriSeq = -1; - bool ok = false; - oriSeq = regExp.capturedTexts()[2].toInt(&ok); - if (ok && oriSeq == p_seq) { - return; - } - - QTextCursor cursor(p_block); - bool ret = cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, - regExp.capturedTexts()[1].size()); - if (!ret) { - return; - } - - ret = cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, - regExp.capturedTexts()[2].size()); - if (!ret) { - return; - } - - cursor.removeSelectedText(); - cursor.insertText(QString::number(p_seq)); -} - -bool VMdEditOperations::decorateHeading(int p_level) -{ - QTextDocument *doc = m_editor->documentW(); - QTextCursor cursor = m_editor->textCursorW(); - int firstBlock = cursor.block().blockNumber(); - int lastBlock = firstBlock; - - if (cursor.hasSelection()) { - // Insert title # in front of the selected blocks. - int start = cursor.selectionStart(); - int end = cursor.selectionEnd(); - firstBlock = doc->findBlock(start).blockNumber(); - lastBlock = doc->findBlock(end).blockNumber(); - } - - cursor.beginEditBlock(); - for (int i = firstBlock; i <= lastBlock; ++i) { - VEditUtils::insertTitleMark(cursor, doc->findBlockByNumber(i), p_level); - } - - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); - return true; -} - -void VMdEditOperations::decorateText(TextDecoration p_decoration, int p_level) -{ - if (p_decoration == TextDecoration::None) { - return; - } - - bool validDecoration = true; - switch (p_decoration) { - case TextDecoration::Bold: - decorateBold(); - break; - - case TextDecoration::Italic: - decorateItalic(); - break; - - case TextDecoration::Strikethrough: - decorateStrikethrough(); - break; - - case TextDecoration::InlineCode: - decorateInlineCode(); - break; - - case TextDecoration::CodeBlock: - decorateCodeBlock(); - break; - - case TextDecoration::Heading: - decorateHeading(p_level); - break; - - default: - validDecoration = false; - qDebug() << "decoration" << (int)p_decoration << "is not implemented yet"; - break; - } - - if (validDecoration && m_editConfig->m_enableVimMode) { - Q_ASSERT(m_vim); - m_vim->setMode(VimMode::Insert, false); - } -} - -void VMdEditOperations::decorateBold() -{ - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - if (cursor.hasSelection()) { - // Insert ** around the selected text. - int start = cursor.selectionStart(); - int end = cursor.selectionEnd(); - cursor.clearSelection(); - cursor.setPosition(start, QTextCursor::MoveAnchor); - cursor.insertText("**"); - cursor.setPosition(end + 2, QTextCursor::MoveAnchor); - cursor.insertText("**"); - } else { - // Insert **** and place cursor in the middle. - // Or if there are two * after current cursor, just skip them or delete - // them if four * appear. - int pos = cursor.positionInBlock(); - bool hasStars = false; - bool emptyMarkers = false; - QString text = cursor.block().text(); - if (pos <= text.size() - 2) { - if (text[pos] == '*' && text[pos + 1] == '*') { - hasStars = true; - - if (pos >= 2 - && text[pos - 1] == '*' - && text[pos - 2] == '*') { - emptyMarkers = true; - } - } - } - - if (hasStars) { - if (emptyMarkers) { - cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, 2); - cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 4); - cursor.removeSelectedText(); - } else { - cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2); - } - } else { - cursor.insertText("****"); - cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2); - } - } - - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); -} - -void VMdEditOperations::decorateItalic() -{ - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - if (cursor.hasSelection()) { - // Insert * around the selected text. - int start = cursor.selectionStart(); - int end = cursor.selectionEnd(); - cursor.clearSelection(); - cursor.setPosition(start, QTextCursor::MoveAnchor); - cursor.insertText("*"); - cursor.setPosition(end + 1, QTextCursor::MoveAnchor); - cursor.insertText("*"); - } else { - // Insert ** and place cursor in the middle. - // Or if there are one * after current cursor, just skip them or delete - // them if two * appear. - int pos = cursor.positionInBlock(); - bool hasStar = false; - bool emptyMarkers = false; - QString text = cursor.block().text(); - if (pos <= text.size() - 1) { - if (text[pos] == '*' - && (pos == text.size() - 1 || text[pos + 1] != '*')) { - hasStar = true; - - if (pos >= 1 && text[pos - 1] == '*') { - emptyMarkers = true; - } - } - } - - if (hasStar) { - if (emptyMarkers) { - cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, 1); - cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 2); - cursor.removeSelectedText(); - } else { - cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1); - } - } else { - cursor.insertText("**"); - cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1); - } - } - - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); -} - -void VMdEditOperations::decorateInlineCode() -{ - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - if (cursor.hasSelection()) { - // Insert ` around the selected text. - int start = cursor.selectionStart(); - int end = cursor.selectionEnd(); - cursor.clearSelection(); - cursor.setPosition(start, QTextCursor::MoveAnchor); - cursor.insertText("`"); - cursor.setPosition(end + 1, QTextCursor::MoveAnchor); - cursor.insertText("`"); - } else { - // Insert `` and place cursor in the middle. - // Or if there are one ` after current cursor, just skip them or delete - // them if two ` appear. - int pos = cursor.positionInBlock(); - bool hasBackquote = false; - bool emptyMarkers = false; - QString text = cursor.block().text(); - if (pos <= text.size() - 1) { - if (text[pos] == '`') { - hasBackquote = true; - - if (pos >= 1 && text[pos - 1] == '`') { - emptyMarkers = true; - } - } - } - - if (hasBackquote) { - if (emptyMarkers) { - cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, 1); - cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 2); - cursor.removeSelectedText(); - } else { - cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1); - } - } else { - cursor.insertText("``"); - cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1); - } - } - - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); -} - -void VMdEditOperations::decorateCodeBlock() -{ - const QString marker("```"); - - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - if (cursor.hasSelection()) { - // Insert ``` around the selected text. - int start = cursor.selectionStart(); - int end = cursor.selectionEnd(); - - QString indentation = VEditUtils::fetchIndentSpaces(cursor.block()); - - // Insert the end marker first. - cursor.setPosition(end, QTextCursor::MoveAnchor); - VEditUtils::insertBlock(cursor, false); - VEditUtils::indentBlock(cursor, indentation); - cursor.insertText(marker); - - // Insert the start marker. - cursor.setPosition(start, QTextCursor::MoveAnchor); - VEditUtils::insertBlock(cursor, true); - VEditUtils::indentBlock(cursor, indentation); - cursor.insertText(marker); - } else { - // Insert ``` ``` and place cursor after the first marker. - // Or if current block or next block is ```, we will skip it. - QTextBlock block = cursor.block(); - int state = block.userState(); - if (state == HighlightBlockState::CodeBlock - || state == HighlightBlockState::CodeBlockStart - || state == HighlightBlockState::CodeBlockEnd) { - // Find the block end. - QTextBlock endBlock = block; - while (endBlock.isValid()) { - if (endBlock.userState() == HighlightBlockState::CodeBlockEnd) { - break; - } - - endBlock = endBlock.next(); - } - - if (endBlock.isValid()) { - // It is CodeBlockEnd. - if (endBlock.previous().isValid() - && endBlock.previous().userState() == HighlightBlockState::CodeBlockStart) { - // Delete empty code blocks. - cursor.setPosition(endBlock.previous().position()); - cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor); - cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); - cursor.removeSelectedText(); - } else { - cursor.setPosition(endBlock.position()); - if (endBlock.next().isValid()) { - cursor.movePosition(QTextCursor::NextBlock); - cursor.movePosition(QTextCursor::StartOfBlock); - } else { - cursor.movePosition(QTextCursor::EndOfBlock); - } - } - } else { - // Reach the end of the document. - cursor.movePosition(QTextCursor::End); - } - } else { - bool insertInline = false; - if (!cursor.atBlockEnd()) { - cursor.insertBlock(); - cursor.movePosition(QTextCursor::PreviousBlock); - } else if (cursor.atBlockStart() || VEditUtils::isSpaceBlock(block)) { - insertInline = true; - } - - if (!insertInline) { - VEditUtils::insertBlock(cursor, false); - VEditUtils::indentBlockAsBlock(cursor, false); - } - - cursor.insertText(marker); - - VEditUtils::insertBlock(cursor, true); - VEditUtils::indentBlockAsBlock(cursor, true); - cursor.insertText(marker); - } - } - - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); -} - -void VMdEditOperations::decorateStrikethrough() -{ - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - if (cursor.hasSelection()) { - // Insert ~~ around the selected text. - int start = cursor.selectionStart(); - int end = cursor.selectionEnd(); - cursor.clearSelection(); - cursor.setPosition(start, QTextCursor::MoveAnchor); - cursor.insertText("~~"); - cursor.setPosition(end + 2, QTextCursor::MoveAnchor); - cursor.insertText("~~"); - } else { - // Insert ~~~~ and place cursor in the middle. - // Or if there are one ~~ after current cursor, just skip it or delete - // it if for ~ appear. - int pos = cursor.positionInBlock(); - bool hasStrikethrough = false; - bool emptyMarkers = false; - QString text = cursor.block().text(); - if (pos <= text.size() - 2) { - if (text[pos] == '~' && text[pos + 1] == '~') { - hasStrikethrough = true; - - if (pos >= 2 - && text[pos - 1] == '~' - && text[pos - 2] == '~') { - emptyMarkers = true; - } - } - } - - if (hasStrikethrough) { - if (emptyMarkers) { - cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, 2); - cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 4); - cursor.removeSelectedText(); - } else { - cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2); - } - } else { - cursor.insertText("~~~~"); - cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2); - } - } - - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); -} - -bool VMdEditOperations::insertLink(const QString &p_linkText, - const QString &p_linkUrl) -{ - QString link = QString("[%1](%2)").arg(p_linkText).arg(p_linkUrl); - QTextCursor cursor = m_editor->textCursorW(); - cursor.insertText(link); - m_editor->setTextCursorW(cursor); - - setVimMode(VimMode::Insert); - - return true; -} diff --git a/src/vmdeditoperations.h b/src/vmdeditoperations.h deleted file mode 100644 index dc53e03d..00000000 --- a/src/vmdeditoperations.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef VMDEDITOPERATIONS_H -#define VMDEDITOPERATIONS_H - -#include -#include -#include -#include -#include -#include "veditoperations.h" - -class QTimer; - -// Editor operations for Markdown -class VMdEditOperations : public VEditOperations -{ - Q_OBJECT -public: - VMdEditOperations(VEditor *p_editor, VFile *p_file); - - bool insertImageFromMimeData(const QMimeData *source) Q_DECL_OVERRIDE; - - bool insertImage() Q_DECL_OVERRIDE; - - bool handleKeyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - - bool insertImageFromURL(const QUrl &p_imageUrl) Q_DECL_OVERRIDE; - - bool insertLink(const QString &p_linkText, - const QString &p_linkUrl) Q_DECL_OVERRIDE; - - // Insert decoration markers or decorate selected text. - // If it is Vim Normal mode, change to Insert mode first. - void decorateText(TextDecoration p_decoration, int p_level = -1) Q_DECL_OVERRIDE; - -private: - // Insert image from @oriImagePath as @path. - // @folderInLink: the folder part in the image link. - void insertImageFromPath(const QString &title, const QString &path, - const QString &folderInLink, const QString &oriImagePath); - - // @title: title of the inserted image; - // @path: the image folder path to insert the image in; - // @folderInLink: the folder part in the image link. - // @image: the image to be inserted; - void insertImageFromQImage(const QString &title, const QString &path, - const QString &folderInLink, const QImage &image); - - // Key press handlers. - bool handleKeyTab(QKeyEvent *p_event); - bool handleKeyBackTab(QKeyEvent *p_event); - bool handleKeyH(QKeyEvent *p_event); - bool handleKeyU(QKeyEvent *p_event); - bool handleKeyW(QKeyEvent *p_event); - bool handleKeyEsc(QKeyEvent *p_event); - bool handleKeyReturn(QKeyEvent *p_event); - bool handleKeyBracketLeft(QKeyEvent *p_event); - - // Change the sequence number of a list block. - void changeListBlockSeqNumber(QTextBlock &p_block, int p_seq); - - // Insert bold marker or set selected text bold. - void decorateBold(); - - // Insert italic marker or set selected text italic. - void decorateItalic(); - - // Insert inline-code marker or set selected text inline-coded. - void decorateInlineCode(); - - // Insert inline-code marker or set selected text inline-coded. - void decorateCodeBlock(); - - // Insert strikethrough marker or set selected text strikethrough. - void decorateStrikethrough(); - - // Insert title of level @p_level. - // Will detect if current block already has some leading #s. If yes, - // will delete it and insert the correct #s. - // @p_level: 0 to cancel title. - bool decorateHeading(int p_level); - - // The cursor position after auto indent or auto list. - // It will be -1 if last key press do not trigger the auto indent or auto list. - int m_autoIndentPos; - - static const QString c_defaultImageTitle; -}; - -#endif // VMDEDITOPERATIONS_H diff --git a/src/vmdeditor.cpp b/src/vmdeditor.cpp deleted file mode 100644 index 56964562..00000000 --- a/src/vmdeditor.cpp +++ /dev/null @@ -1,992 +0,0 @@ -#include "vmdeditor.h" - -#include -#include -#include - -#include "vdocument.h" -#include "utils/veditutils.h" -#include "vedittab.h" -#include "hgmarkdownhighlighter.h" -#include "vcodeblockhighlighthelper.h" -#include "vmdeditoperations.h" -#include "vtableofcontent.h" -#include "utils/veditutils.h" -#include "dialog/vselectdialog.h" -#include "dialog/vconfirmdeletiondialog.h" -#include "vtextblockdata.h" -#include "vorphanfile.h" -#include "vnotefile.h" -#include "vpreviewmanager.h" -#include "utils/viconutils.h" - -extern VConfigManager *g_config; - -VMdEditor::VMdEditor(VFile *p_file, - VDocument *p_doc, - MarkdownConverterType p_type, - QWidget *p_parent) - : VTextEdit(p_parent), - VEditor(p_file, this), - m_mdHighlighter(NULL), - m_freshEdit(true) -{ - Q_ASSERT(p_file->getDocType() == DocType::Markdown); - - VEditor::init(); - - // Hook functions from VEditor. - connect(this, &VTextEdit::cursorPositionChanged, - this, [this]() { - highlightOnCursorPositionChanged(); - }); - - connect(this, &VTextEdit::selectionChanged, - this, [this]() { - highlightSelectedWord(); - }); - // End. - - setReadOnly(true); - - m_mdHighlighter = new HGMarkdownHighlighter(g_config->getMdHighlightingStyles(), - g_config->getCodeBlockStyles(), - g_config->getMarkdownHighlightInterval(), - document()); - - connect(m_mdHighlighter, &HGMarkdownHighlighter::headersUpdated, - this, &VMdEditor::updateHeaders); - - // After highlight, the cursor may trun into non-visible. We should make it visible - // in this case. - connect(m_mdHighlighter, &HGMarkdownHighlighter::highlightCompleted, - this, [this]() { - makeBlockVisible(textCursor().block()); - - if (m_freshEdit) { - m_freshEdit = false; - emit m_object->ready(); - } - }); - - m_cbHighlighter = new VCodeBlockHighlightHelper(m_mdHighlighter, - p_doc, - p_type); - - m_previewMgr = new VPreviewManager(this, m_mdHighlighter); - connect(m_mdHighlighter, &HGMarkdownHighlighter::imageLinksUpdated, - m_previewMgr, &VPreviewManager::imageLinksUpdated); - connect(m_previewMgr, &VPreviewManager::requestUpdateImageLinks, - m_mdHighlighter, &HGMarkdownHighlighter::updateHighlight); - - m_editOps = new VMdEditOperations(this, m_file); - connect(m_editOps, &VEditOperations::statusMessage, - m_object, &VEditorObject::statusMessage); - connect(m_editOps, &VEditOperations::vimStatusUpdated, - m_object, &VEditorObject::vimStatusUpdated); - - connect(this, &VTextEdit::cursorPositionChanged, - this, &VMdEditor::updateCurrentHeader); - - updateFontAndPalette(); - - updateConfig(); -} - -void VMdEditor::updateFontAndPalette() -{ - setFont(g_config->getMdEditFont()); - setPalette(g_config->getMdEditPalette()); - - // setPalette() won't change the foreground. - setTextColor(g_config->getMdEditPalette().color(QPalette::Text)); -} - -void VMdEditor::beginEdit() -{ - updateConfig(); - - initInitImages(); - - setModified(false); - - setReadOnlyAndHighlightCurrentLine(false); - - emit statusChanged(); - - if (m_freshEdit) { - m_mdHighlighter->updateHighlight(); - relayout(); - } else { - updateHeaders(m_mdHighlighter->getHeaderRegions()); - } -} - -void VMdEditor::endEdit() -{ - setReadOnlyAndHighlightCurrentLine(true); - - clearUnusedImages(); -} - -void VMdEditor::saveFile() -{ - Q_ASSERT(m_file->isModifiable()); - - if (!document()->isModified()) { - return; - } - - m_file->setContent(toPlainText()); - setModified(false); - - clearUnusedImages(); - - initInitImages(); -} - -void VMdEditor::reloadFile() -{ - bool readonly = isReadOnly(); - setReadOnly(true); - - const QString &content = m_file->getContent(); - setPlainText(content); - setModified(false); - m_mdHighlighter->updateHighlightFast(); - - m_freshEdit = true; - - setReadOnly(readonly); -} - -bool VMdEditor::scrollToBlock(int p_blockNumber) -{ - QTextBlock block = document()->findBlockByNumber(p_blockNumber); - if (block.isValid()) { - VEditUtils::scrollBlockInPage(this, block.blockNumber(), 0); - moveCursor(QTextCursor::EndOfBlock); - return true; - } - - return false; -} - -// Get the visual offset of a block. -#define GETVISUALOFFSETY (contentOffsetY() + (int)rect.y()) - -void VMdEditor::makeBlockVisible(const QTextBlock &p_block) -{ - if (!p_block.isValid() || !p_block.isVisible()) { - return; - } - - QScrollBar *vbar = verticalScrollBar(); - if (!vbar || (vbar->minimum() == vbar->maximum())) { - // No vertical scrollbar. No need to scroll. - return; - } - - int height = rect().height(); - QScrollBar *hbar = horizontalScrollBar(); - if (hbar && (hbar->minimum() != hbar->maximum())) { - height -= hbar->height(); - } - - bool moved = false; - - QAbstractTextDocumentLayout *layout = document()->documentLayout(); - QRectF rect = layout->blockBoundingRect(p_block); - int y = GETVISUALOFFSETY; - int rectHeight = (int)rect.height(); - - // Handle the case rectHeight >= height. - if (rectHeight >= height) { - if (y < 0) { - // Need to scroll up. - while (y + rectHeight < height && vbar->value() > vbar->minimum()) { - moved = true; - vbar->setValue(vbar->value() - vbar->singleStep()); - rect = layout->blockBoundingRect(p_block); - rectHeight = (int)rect.height(); - y = GETVISUALOFFSETY; - } - } else if (y > 0) { - // Need to scroll down. - while (y > 0 && vbar->value() < vbar->maximum()) { - moved = true; - vbar->setValue(vbar->value() + vbar->singleStep()); - rect = layout->blockBoundingRect(p_block); - rectHeight = (int)rect.height(); - y = GETVISUALOFFSETY; - } - - if (y < 0) { - // One step back. - moved = true; - vbar->setValue(vbar->value() - vbar->singleStep()); - } - } - - if (moved) { - qDebug() << "scroll to make huge block visible"; - } - - return; - } - - while (y < 0 && vbar->value() > vbar->minimum()) { - moved = true; - vbar->setValue(vbar->value() - vbar->singleStep()); - rect = layout->blockBoundingRect(p_block); - rectHeight = (int)rect.height(); - y = GETVISUALOFFSETY; - } - - if (moved) { - qDebug() << "scroll page down to make block visible"; - return; - } - - while (y + rectHeight > height && vbar->value() < vbar->maximum()) { - moved = true; - vbar->setValue(vbar->value() + vbar->singleStep()); - rect = layout->blockBoundingRect(p_block); - rectHeight = (int)rect.height(); - y = GETVISUALOFFSETY; - } - - if (moved) { - qDebug() << "scroll page up to make block visible"; - } -} - -void VMdEditor::contextMenuEvent(QContextMenuEvent *p_event) -{ - QMenu *menu = createStandardContextMenu(); - menu->setToolTipsVisible(true); - - const QList actions = menu->actions(); - - if (!textCursor().hasSelection()) { - VEditTab *editTab = dynamic_cast(parent()); - Q_ASSERT(editTab); - if (editTab->isEditMode()) { - QAction *saveExitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/save_exit.svg"), - tr("&Save Changes And Read"), - menu); - saveExitAct->setToolTip(tr("Save changes and exit edit mode")); - connect(saveExitAct, &QAction::triggered, - this, [this]() { - emit m_object->saveAndRead(); - }); - - QAction *discardExitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/discard_exit.svg"), - tr("&Discard Changes And Read"), - menu); - discardExitAct->setToolTip(tr("Discard changes and exit edit mode")); - connect(discardExitAct, &QAction::triggered, - this, [this]() { - emit m_object->discardAndRead(); - }); - - menu->insertAction(actions.isEmpty() ? NULL : actions[0], discardExitAct); - menu->insertAction(discardExitAct, saveExitAct); - if (!actions.isEmpty()) { - menu->insertSeparator(actions[0]); - } - } - } - - menu->exec(p_event->globalPos()); - delete menu; -} - -void VMdEditor::mousePressEvent(QMouseEvent *p_event) -{ - if (handleMousePressEvent(p_event)) { - return; - } - - VTextEdit::mousePressEvent(p_event); - - emit m_object->mousePressed(p_event); -} - -void VMdEditor::mouseReleaseEvent(QMouseEvent *p_event) -{ - if (handleMouseReleaseEvent(p_event)) { - return; - } - - VTextEdit::mouseReleaseEvent(p_event); - - emit m_object->mouseReleased(p_event); -} - -void VMdEditor::mouseMoveEvent(QMouseEvent *p_event) -{ - if (handleMouseMoveEvent(p_event)) { - return; - } - - VTextEdit::mouseMoveEvent(p_event); - - emit m_object->mouseMoved(p_event); -} - -QVariant VMdEditor::inputMethodQuery(Qt::InputMethodQuery p_query) const -{ - QVariant ret; - if (handleInputMethodQuery(p_query, ret)) { - return ret; - } - - return VTextEdit::inputMethodQuery(p_query); -} - -bool VMdEditor::isBlockVisible(const QTextBlock &p_block) -{ - if (!p_block.isValid() || !p_block.isVisible()) { - return false; - } - - QScrollBar *vbar = verticalScrollBar(); - if (!vbar || !vbar->isVisible()) { - // No vertical scrollbar. - return true; - } - - int height = rect().height(); - QScrollBar *hbar = horizontalScrollBar(); - if (hbar && hbar->isVisible()) { - height -= hbar->height(); - } - - QAbstractTextDocumentLayout *layout = document()->documentLayout(); - QRectF rect = layout->blockBoundingRect(p_block); - int y = GETVISUALOFFSETY; - int rectHeight = (int)rect.height(); - - return (y >= 0 && y < height) || (y < 0 && y + rectHeight > 0); -} - -static void addHeaderSequence(QVector &p_sequence, int p_level, int p_baseLevel) -{ - Q_ASSERT(p_level >= 1 && p_level < p_sequence.size()); - if (p_level < p_baseLevel) { - p_sequence.fill(0); - return; - } - - ++p_sequence[p_level]; - for (int i = p_level + 1; i < p_sequence.size(); ++i) { - p_sequence[i] = 0; - } -} - -static QString headerSequenceStr(const QVector &p_sequence) -{ - QString res; - for (int i = 1; i < p_sequence.size(); ++i) { - if (p_sequence[i] != 0) { - res = res + QString::number(p_sequence[i]) + '.'; - } else if (res.isEmpty()) { - continue; - } else { - break; - } - } - - return res; -} - -static void insertSequenceToHeader(QTextBlock p_block, - QRegExp &p_reg, - QRegExp &p_preReg, - const QString &p_seq) -{ - if (!p_block.isValid()) { - return; - } - - QString text = p_block.text(); - bool matched = p_reg.exactMatch(text); - Q_ASSERT(matched); - - matched = p_preReg.exactMatch(text); - Q_ASSERT(matched); - - int start = p_reg.cap(1).length() + 1; - int end = p_preReg.cap(1).length(); - - Q_ASSERT(start <= end); - - QTextCursor cursor(p_block); - cursor.setPosition(p_block.position() + start); - if (start != end) { - cursor.setPosition(p_block.position() + end, QTextCursor::KeepAnchor); - } - - if (p_seq.isEmpty()) { - cursor.removeSelectedText(); - } else { - cursor.insertText(p_seq + ' '); - } -} - -void VMdEditor::updateHeaders(const QVector &p_headerRegions) -{ - QTextDocument *doc = document(); - - QVector headers; - QVector headerBlockNumbers; - QVector headerSequences; - if (!p_headerRegions.isEmpty()) { - headers.reserve(p_headerRegions.size()); - headerBlockNumbers.reserve(p_headerRegions.size()); - headerSequences.reserve(p_headerRegions.size()); - } - - // Assume that each block contains only one line - // Only support # syntax for now - QRegExp headerReg(VUtils::c_headerRegExp); - int baseLevel = -1; - for (auto const & reg : p_headerRegions) { - QTextBlock block = doc->findBlock(reg.m_startPos); - if (!block.isValid()) { - continue; - } - - if (!block.contains(reg.m_endPos - 1)) { - qWarning() << "header accross multiple blocks, starting from block" - << block.blockNumber() - << block.text(); - } - - if ((block.userState() == HighlightBlockState::Normal) - && headerReg.exactMatch(block.text())) { - int level = headerReg.cap(1).length(); - VTableOfContentItem header(headerReg.cap(2).trimmed(), - level, - block.blockNumber(), - headers.size()); - headers.append(header); - headerBlockNumbers.append(block.blockNumber()); - headerSequences.append(headerReg.cap(3)); - - if (baseLevel == -1) { - baseLevel = level; - } else if (baseLevel > level) { - baseLevel = level; - } - } - } - - m_headers.clear(); - - bool autoSequence = m_config.m_enableHeadingSequence - && !isReadOnly() - && m_file->isModifiable(); - int headingSequenceBaseLevel = g_config->getHeadingSequenceBaseLevel(); - if (headingSequenceBaseLevel < 1 || headingSequenceBaseLevel > 6) { - headingSequenceBaseLevel = 1; - } - - QVector seqs(7, 0); - QRegExp preReg(VUtils::c_headerPrefixRegExp); - int curLevel = baseLevel - 1; - for (int i = 0; i < headers.size(); ++i) { - VTableOfContentItem &item = headers[i]; - while (item.m_level > curLevel + 1) { - curLevel += 1; - - // Insert empty level which is an invalid header. - m_headers.append(VTableOfContentItem(c_emptyHeaderName, - curLevel, - -1, - m_headers.size())); - if (autoSequence) { - addHeaderSequence(seqs, curLevel, headingSequenceBaseLevel); - } - } - - item.m_index = m_headers.size(); - m_headers.append(item); - curLevel = item.m_level; - if (autoSequence) { - addHeaderSequence(seqs, item.m_level, headingSequenceBaseLevel); - - QString seqStr = headerSequenceStr(seqs); - if (headerSequences[i] != seqStr) { - // Insert correct sequence. - insertSequenceToHeader(doc->findBlockByNumber(headerBlockNumbers[i]), - headerReg, - preReg, - seqStr); - } - } - } - - emit headersChanged(m_headers); - - updateCurrentHeader(); -} - -void VMdEditor::updateCurrentHeader() -{ - emit currentHeaderChanged(textCursor().block().blockNumber()); -} - -void VMdEditor::initInitImages() -{ - m_initImages = VUtils::fetchImagesFromMarkdownFile(m_file, - ImageLink::LocalRelativeInternal); -} - -void VMdEditor::clearUnusedImages() -{ - QVector images = VUtils::fetchImagesFromMarkdownFile(m_file, - ImageLink::LocalRelativeInternal); - - QSet unusedImages; - - if (!m_insertedImages.isEmpty()) { - for (int i = 0; i < m_insertedImages.size(); ++i) { - const ImageLink &link = m_insertedImages[i]; - - if (link.m_type != ImageLink::LocalRelativeInternal) { - continue; - } - - int j; - for (j = 0; j < images.size(); ++j) { - if (VUtils::equalPath(link.m_path, images[j].m_path)) { - break; - } - } - - // This inserted image is no longer in the file. - if (j == images.size()) { - unusedImages.insert(link.m_path); - } - } - - m_insertedImages.clear(); - } - - for (int i = 0; i < m_initImages.size(); ++i) { - const ImageLink &link = m_initImages[i]; - - V_ASSERT(link.m_type == ImageLink::LocalRelativeInternal); - - int j; - for (j = 0; j < images.size(); ++j) { - if (VUtils::equalPath(link.m_path, images[j].m_path)) { - break; - } - } - - // Original local relative image is no longer in the file. - if (j == images.size()) { - unusedImages.insert(link.m_path); - } - } - - if (!unusedImages.isEmpty()) { - if (g_config->getConfirmImagesCleanUp()) { - QVector items; - for (auto const & img : unusedImages) { - items.push_back(ConfirmItemInfo(img, - img, - img, - NULL)); - - } - - QString text = tr("Following images seems not to be used in this note anymore. " - "Please confirm the deletion of these images."); - - QString info = tr("Deleted files could be found in the recycle " - "bin of this note.
    " - "Click \"Cancel\" to leave them untouched."); - - VConfirmDeletionDialog dialog(tr("Confirm Cleaning Up Unused Images"), - text, - info, - items, - true, - true, - true, - this); - - unusedImages.clear(); - if (dialog.exec()) { - items = dialog.getConfirmedItems(); - g_config->setConfirmImagesCleanUp(dialog.getAskAgainEnabled()); - - for (auto const & item : items) { - unusedImages.insert(item.m_name); - } - } - } - - for (auto const & item : unusedImages) { - bool ret = false; - if (m_file->getType() == FileType::Note) { - const VNoteFile *tmpFile = dynamic_cast((VFile *)m_file); - ret = VUtils::deleteFile(tmpFile->getNotebook(), item, false); - } else if (m_file->getType() == FileType::Orphan) { - const VOrphanFile *tmpFile = dynamic_cast((VFile *)m_file); - ret = VUtils::deleteFile(tmpFile, item, false); - } else { - Q_ASSERT(false); - } - - if (!ret) { - qWarning() << "fail to delete unused original image" << item; - } else { - qDebug() << "delete unused image" << item; - } - } - } - - m_initImages.clear(); -} - -void VMdEditor::keyPressEvent(QKeyEvent *p_event) -{ - if (m_editOps && m_editOps->handleKeyPressEvent(p_event)) { - return; - } - - VTextEdit::keyPressEvent(p_event); -} - -bool VMdEditor::canInsertFromMimeData(const QMimeData *p_source) const -{ - return p_source->hasImage() - || p_source->hasUrls() - || VTextEdit::canInsertFromMimeData(p_source); -} - -void VMdEditor::insertFromMimeData(const QMimeData *p_source) -{ - VSelectDialog dialog(tr("Insert From Clipboard"), this); - dialog.addSelection(tr("Insert As Image"), 0); - dialog.addSelection(tr("Insert As Text"), 1); - - if (p_source->hasImage()) { - // Image data in the clipboard - if (p_source->hasText()) { - if (dialog.exec() == QDialog::Accepted) { - if (dialog.getSelection() == 1) { - // Insert as text. - Q_ASSERT(p_source->hasText() && p_source->hasImage()); - VTextEdit::insertFromMimeData(p_source); - return; - } - } else { - return; - } - } - - m_editOps->insertImageFromMimeData(p_source); - return; - } else if (p_source->hasUrls()) { - QList urls = p_source->urls(); - if (urls.size() == 1 && VUtils::isImageURL(urls[0])) { - if (dialog.exec() == QDialog::Accepted) { - // FIXME: After calling dialog.exec(), p_source->hasUrl() returns false. - if (dialog.getSelection() == 0) { - // Insert as image. - m_editOps->insertImageFromURL(urls[0]); - return; - } - - QMimeData newSource; - newSource.setUrls(urls); - VTextEdit::insertFromMimeData(&newSource); - return; - } else { - return; - } - } - } else if (p_source->hasText()) { - QString text = p_source->text(); - if (VUtils::isImageURLText(text)) { - // The text is a URL to an image. - if (dialog.exec() == QDialog::Accepted) { - if (dialog.getSelection() == 0) { - // Insert as image. - QUrl url(text); - if (url.isValid()) { - m_editOps->insertImageFromURL(QUrl(text)); - } - return; - } - } else { - return; - } - } - - Q_ASSERT(p_source->hasText()); - } - - VTextEdit::insertFromMimeData(p_source); -} - -void VMdEditor::imageInserted(const QString &p_path, const QString &p_url) -{ - ImageLink link; - link.m_path = p_path; - link.m_url = p_url; - if (m_file->useRelativeImageFolder()) { - link.m_type = ImageLink::LocalRelativeInternal; - } else { - link.m_type = ImageLink::LocalAbsolute; - } - - m_insertedImages.append(link); -} - -bool VMdEditor::scrollToHeader(int p_blockNumber) -{ - if (p_blockNumber < 0) { - return false; - } - - return scrollToBlock(p_blockNumber); -} - -int VMdEditor::indexOfCurrentHeader() const -{ - if (m_headers.isEmpty()) { - return -1; - } - - int blockNumber = textCursor().block().blockNumber(); - for (int i = m_headers.size() - 1; i >= 0; --i) { - if (!m_headers[i].isEmpty() - && m_headers[i].m_blockNumber <= blockNumber) { - return i; - } - } - - return -1; -} - -bool VMdEditor::jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat) -{ - if (m_headers.isEmpty()) { - return false; - } - - QTextCursor cursor = textCursor(); - int cursorLine = cursor.block().blockNumber(); - int targetIdx = -1; - // -1: skip level check. - int targetLevel = 0; - int idx = indexOfCurrentHeader(); - if (idx == -1) { - // Cursor locates at the beginning, before any headers. - if (p_relativeLevel < 0 || !p_forward) { - return false; - } - } - - int delta = 1; - if (!p_forward) { - delta = -1; - } - - bool firstHeader = true; - for (targetIdx = idx == -1 ? 0 : idx; - targetIdx >= 0 && targetIdx < m_headers.size(); - targetIdx += delta) { - const VTableOfContentItem &header = m_headers[targetIdx]; - if (header.isEmpty()) { - continue; - } - - if (targetLevel == 0) { - // The target level has not been init yet. - Q_ASSERT(firstHeader); - targetLevel = header.m_level; - if (p_relativeLevel < 0) { - targetLevel += p_relativeLevel; - if (targetLevel < 1) { - // Invalid level. - return false; - } - } else if (p_relativeLevel > 0) { - targetLevel = -1; - } - } - - if (targetLevel == -1 || header.m_level == targetLevel) { - if (firstHeader - && (cursorLine == header.m_blockNumber - || p_forward) - && idx != -1) { - // This header is not counted for the repeat. - firstHeader = false; - continue; - } - - if (--p_repeat == 0) { - // Found. - break; - } - } else if (header.m_level < targetLevel) { - // Stop by higher level. - return false; - } - - firstHeader = false; - } - - if (targetIdx < 0 || targetIdx >= m_headers.size()) { - return false; - } - - // Jump to target header. - int line = m_headers[targetIdx].m_blockNumber; - if (line > -1) { - QTextBlock block = document()->findBlockByNumber(line); - if (block.isValid()) { - cursor.setPosition(block.position()); - setTextCursor(cursor); - return true; - } - } - - return false; -} - -void VMdEditor::scrollBlockInPage(int p_blockNum, int p_dest) -{ - VEditUtils::scrollBlockInPage(this, p_blockNum, p_dest); -} - -void VMdEditor::updateTextEditConfig() -{ - setBlockImageEnabled(g_config->getEnablePreviewImages()); - - setImageWidthConstrainted(g_config->getEnablePreviewImageConstraint()); - - setLineLeading(m_config.m_lineDistanceHeight); - - setImageLineColor(g_config->getEditorPreviewImageLineFg()); - - int lineNumber = g_config->getEditorLineNumber(); - if (lineNumber < (int)LineNumberType::None || lineNumber >= (int)LineNumberType::Invalid) { - lineNumber = (int)LineNumberType::None; - } - - setLineNumberType((LineNumberType)lineNumber); - setLineNumberColor(g_config->getEditorLineNumberFg(), - g_config->getEditorLineNumberBg()); - - m_previewMgr->setPreviewEnabled(g_config->getEnablePreviewImages()); -} - -void VMdEditor::updateConfig() -{ - updateEditConfig(); - updateTextEditConfig(); -} - -QString VMdEditor::getContent() const -{ - return toPlainText(); -} - -void VMdEditor::setContent(const QString &p_content, bool p_modified) -{ - if (p_modified) { - QTextCursor cursor = textCursor(); - cursor.select(QTextCursor::Document); - cursor.insertText(p_content); - setTextCursor(cursor); - } else { - setPlainText(p_content); - } -} - -void VMdEditor::refreshPreview() -{ - m_previewMgr->refreshPreview(); -} - -void VMdEditor::updateInitAndInsertedImages(bool p_fileChanged, UpdateAction p_act) -{ - if (p_fileChanged && p_act == UpdateAction::InfoChanged) { - return; - } - - if (!isModified()) { - Q_ASSERT(m_insertedImages.isEmpty()); - m_insertedImages.clear(); - - if (!m_initImages.isEmpty()) { - // Re-generate init images. - initInitImages(); - } - - return; - } - - // Update init images. - QVector tmp = m_initImages; - initInitImages(); - Q_ASSERT(tmp.size() == m_initImages.size()); - - QDir dir(m_file->fetchBasePath()); - - // File has been moved. - if (p_fileChanged) { - // Since we clear unused images once user save the note, all images - // in m_initImages now are moved already. - - // Update inserted images. - // Inserted images should be moved manually here. Then update all the - // paths. - for (auto & link : m_insertedImages) { - if (link.m_type == ImageLink::LocalAbsolute) { - continue; - } - - QString newPath = QDir::cleanPath(dir.absoluteFilePath(link.m_url)); - if (VUtils::equalPath(link.m_path, newPath)) { - continue; - } - - if (!VUtils::copyFile(link.m_path, newPath, true)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to move unsaved inserted image %1 to %2.") - .arg(link.m_path) - .arg(newPath), - tr("Please check it manually to avoid image loss."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - continue; - } - - link.m_path = newPath; - } - } else { - // Directory changed. - // Update inserted images. - for (auto & link : m_insertedImages) { - if (link.m_type == ImageLink::LocalAbsolute) { - continue; - } - - QString newPath = QDir::cleanPath(dir.absoluteFilePath(link.m_url)); - link.m_path = newPath; - } - } -} diff --git a/src/vmdeditor.h b/src/vmdeditor.h deleted file mode 100644 index 35aebe57..00000000 --- a/src/vmdeditor.h +++ /dev/null @@ -1,226 +0,0 @@ -#ifndef VMDEDITOR_H -#define VMDEDITOR_H - -#include -#include -#include -#include - -#include "vtextedit.h" -#include "veditor.h" -#include "vconfigmanager.h" -#include "vtableofcontent.h" -#include "vconfigmanager.h" -#include "utils/vutils.h" - -class HGMarkdownHighlighter; -class VCodeBlockHighlightHelper; -class VDocument; -class VPreviewManager; - -class VMdEditor : public VTextEdit, public VEditor -{ - Q_OBJECT -public: - VMdEditor(VFile *p_file, - VDocument *p_doc, - MarkdownConverterType p_type, - QWidget *p_parent = nullptr); - - void beginEdit() Q_DECL_OVERRIDE; - - void endEdit() Q_DECL_OVERRIDE; - - void saveFile() Q_DECL_OVERRIDE; - - void reloadFile() Q_DECL_OVERRIDE; - - bool scrollToBlock(int p_blockNumber) Q_DECL_OVERRIDE; - - void makeBlockVisible(const QTextBlock &p_block) Q_DECL_OVERRIDE; - - QVariant inputMethodQuery(Qt::InputMethodQuery p_query) const Q_DECL_OVERRIDE; - - bool isBlockVisible(const QTextBlock &p_block) Q_DECL_OVERRIDE; - - // An image has been inserted. The image is relative. - // @p_path is the absolute path of the inserted image. - // @p_url is the URL text within (). - void imageInserted(const QString &p_path, const QString &p_url); - - // Scroll to header @p_blockNumber. - // Return true if @p_blockNumber is valid to scroll to. - bool scrollToHeader(int p_blockNumber); - - void scrollBlockInPage(int p_blockNum, int p_dest) Q_DECL_OVERRIDE; - - void updateConfig() Q_DECL_OVERRIDE; - - QString getContent() const Q_DECL_OVERRIDE; - - void setContent(const QString &p_content, bool p_modified = false) Q_DECL_OVERRIDE; - - void refreshPreview(); - - // Update m_initImages and m_insertedImages to handle the change of the note path. - void updateInitAndInsertedImages(bool p_fileChanged, UpdateAction p_act); - -public slots: - bool jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat) Q_DECL_OVERRIDE; - -// Wrapper functions for QPlainTextEdit/QTextEdit. -public: - void setExtraSelectionsW(const QList &p_selections) Q_DECL_OVERRIDE - { - setExtraSelections(p_selections); - } - - QTextDocument *documentW() const Q_DECL_OVERRIDE - { - return document(); - } - - void setTabStopWidthW(int p_width) Q_DECL_OVERRIDE - { - setTabStopWidth(p_width); - } - - QTextCursor textCursorW() const Q_DECL_OVERRIDE - { - return textCursor(); - } - - void moveCursorW(QTextCursor::MoveOperation p_operation, - QTextCursor::MoveMode p_mode) Q_DECL_OVERRIDE - { - moveCursor(p_operation, p_mode); - } - - QScrollBar *verticalScrollBarW() const Q_DECL_OVERRIDE - { - return verticalScrollBar(); - } - - QScrollBar *horizontalScrollBarW() const Q_DECL_OVERRIDE - { - return horizontalScrollBar(); - } - - void setTextCursorW(const QTextCursor &p_cursor) Q_DECL_OVERRIDE - { - setTextCursor(p_cursor); - } - - bool findW(const QString &p_exp, - QTextDocument::FindFlags p_options = QTextDocument::FindFlags()) Q_DECL_OVERRIDE - { - return find(p_exp, p_options); - } - - bool findW(const QRegExp &p_exp, - QTextDocument::FindFlags p_options = QTextDocument::FindFlags()) Q_DECL_OVERRIDE - { - return find(p_exp, p_options); - } - - void setReadOnlyW(bool p_ro) Q_DECL_OVERRIDE - { - setReadOnly(p_ro); - } - - QWidget *viewportW() const Q_DECL_OVERRIDE - { - return viewport(); - } - - void insertPlainTextW(const QString &p_text) Q_DECL_OVERRIDE - { - insertPlainText(p_text); - } - - void undoW() Q_DECL_OVERRIDE - { - undo(); - } - - void redoW() Q_DECL_OVERRIDE - { - redo(); - } - - // Whether display cursor as block. - void setCursorBlockModeW(CursorBlock p_mode) Q_DECL_OVERRIDE - { - setCursorBlockMode(p_mode); - } - -signals: - // Signal when headers change. - void headersChanged(const QVector &p_headers); - - // Signal when current header change. - void currentHeaderChanged(int p_blockNumber); - - // Signal when the status of VMdEdit changed. - // Will be emitted by VImagePreviewer for now. - void statusChanged(); - -protected: - void updateFontAndPalette() Q_DECL_OVERRIDE; - - void contextMenuEvent(QContextMenuEvent *p_event) Q_DECL_OVERRIDE; - - // Used to implement dragging mouse with Ctrl and left button pressed to scroll. - void mousePressEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE; - - void mouseReleaseEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE; - - void mouseMoveEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE; - - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - - bool canInsertFromMimeData(const QMimeData *p_source) const Q_DECL_OVERRIDE; - - void insertFromMimeData(const QMimeData *p_source) Q_DECL_OVERRIDE; - -private slots: - // Update m_headers according to elements. - void updateHeaders(const QVector &p_headerRegions); - - // Update current header according to cursor position. - // When there is no header in current cursor, will signal an invalid header. - void updateCurrentHeader(); - -private: - // Update the config of VTextEdit according to global configurations. - void updateTextEditConfig(); - - // Get the initial images from file before edit. - void initInitImages(); - - // Clear two kind of images according to initial images and current images: - // 1. Newly inserted images which are deleted later; - // 2. Initial images which are deleted; - void clearUnusedImages(); - - // Index in m_headers of current header which contains the cursor. - int indexOfCurrentHeader() const; - - HGMarkdownHighlighter *m_mdHighlighter; - - VCodeBlockHighlightHelper *m_cbHighlighter; - - VPreviewManager *m_previewMgr; - - // Image links inserted while editing. - QVector m_insertedImages; - - // Image links right at the beginning of the edit. - QVector m_initImages; - - // Mainly used for title jump. - QVector m_headers; - - bool m_freshEdit; -}; -#endif // VMDEDITOR_H diff --git a/src/vmdtab.cpp b/src/vmdtab.cpp deleted file mode 100644 index bb6c7ae0..00000000 --- a/src/vmdtab.cpp +++ /dev/null @@ -1,999 +0,0 @@ -#include -#include -#include -#include -#include "vmdtab.h" -#include "vdocument.h" -#include "vnote.h" -#include "utils/vutils.h" -#include "vpreviewpage.h" -#include "hgmarkdownhighlighter.h" -#include "vconfigmanager.h" -#include "vmarkdownconverter.h" -#include "vnotebook.h" -#include "vtableofcontent.h" -#include "dialog/vfindreplacedialog.h" -#include "veditarea.h" -#include "vconstants.h" -#include "vwebview.h" -#include "vmdeditor.h" -#include "vmainwindow.h" -#include "vsnippet.h" -#include "vinsertselector.h" -#include "vsnippetlist.h" - -extern VMainWindow *g_mainWin; - -extern VConfigManager *g_config; - -VMdTab::VMdTab(VFile *p_file, VEditArea *p_editArea, - OpenFileMode p_mode, QWidget *p_parent) - : VEditTab(p_file, p_editArea, p_parent), - m_editor(NULL), - m_webViewer(NULL), - m_document(NULL), - m_mdConType(g_config->getMdConverterType()), - m_enableHeadingSequence(false), - m_backupFileChecked(false) -{ - V_ASSERT(m_file->getDocType() == DocType::Markdown); - - m_file->open(); - - HeadingSequenceType headingSequenceType = g_config->getHeadingSequenceType(); - if (headingSequenceType == HeadingSequenceType::Enabled) { - m_enableHeadingSequence = true; - } else if (headingSequenceType == HeadingSequenceType::EnabledNoteOnly - && m_file->getType() == FileType::Note) { - m_enableHeadingSequence = true; - } - - setupUI(); - - m_backupTimer = new QTimer(this); - m_backupTimer->setSingleShot(true); - m_backupTimer->setInterval(g_config->getFileTimerInterval()); - connect(m_backupTimer, &QTimer::timeout, - this, [this]() { - writeBackupFile(); - }); - - if (p_mode == OpenFileMode::Edit) { - showFileEditMode(); - } else { - showFileReadMode(); - } -} - -void VMdTab::setupUI() -{ - m_stacks = new QStackedLayout(this); - - setupMarkdownViewer(); - - // Setup editor when we really need it. - m_editor = NULL; - - setLayout(m_stacks); -} - -void VMdTab::showFileReadMode() -{ - m_isEditMode = false; - - // Will recover the header when web side is ready. - m_headerFromEditMode = m_currentHeader; - - if (m_mdConType == MarkdownConverterType::Hoedown) { - viewWebByConverter(); - } else { - m_document->updateText(); - updateOutlineFromHtml(m_document->getToc()); - } - - m_stacks->setCurrentWidget(m_webViewer); - clearSearchedWordHighlight(); - - updateStatus(); -} - -bool VMdTab::scrollWebViewToHeader(const VHeaderPointer &p_header) -{ - if (!m_outline.isMatched(p_header) - || m_outline.getType() != VTableOfContentType::Anchor) { - return false; - } - - if (p_header.isValid()) { - const VTableOfContentItem *item = m_outline.getItem(p_header); - if (item) { - if (item->m_anchor.isEmpty()) { - return false; - } - - m_currentHeader = p_header; - m_document->scrollToAnchor(item->m_anchor); - } else { - return false; - } - } else { - if (m_outline.isEmpty()) { - // Let it be. - m_currentHeader = p_header; - } else { - // Scroll to top. - m_currentHeader = p_header; - m_document->scrollToAnchor(""); - } - } - - emit currentHeaderChanged(m_currentHeader); - return true; -} - -bool VMdTab::scrollEditorToHeader(const VHeaderPointer &p_header) -{ - if (!m_outline.isMatched(p_header) - || m_outline.getType() != VTableOfContentType::BlockNumber) { - return false; - } - - VMdEditor *mdEdit = getEditor(); - - int blockNumber = -1; - if (p_header.isValid()) { - const VTableOfContentItem *item = m_outline.getItem(p_header); - if (item) { - blockNumber = item->m_blockNumber; - if (blockNumber == -1) { - // Empty item. - return false; - } - } else { - return false; - } - } else { - if (m_outline.isEmpty()) { - // No outline and scroll to -1 index. - // Just let it be. - m_currentHeader = p_header; - return true; - } else { - // Has outline and scroll to -1 index. - // Scroll to top. - blockNumber = 0; - } - } - - if (mdEdit->scrollToHeader(blockNumber)) { - m_currentHeader = p_header; - return true; - } else { - return false; - } -} - -bool VMdTab::scrollToHeaderInternal(const VHeaderPointer &p_header) -{ - if (m_isEditMode) { - return scrollEditorToHeader(p_header); - } else { - return scrollWebViewToHeader(p_header); - } -} - -void VMdTab::viewWebByConverter() -{ - VMarkdownConverter mdConverter; - QString toc; - QString html = mdConverter.generateHtml(m_file->getContent(), - g_config->getMarkdownExtensions(), - toc); - m_document->setHtml(html); - updateOutlineFromHtml(toc); -} - -void VMdTab::showFileEditMode() -{ - VHeaderPointer header(m_currentHeader); - - m_isEditMode = true; - - VMdEditor *mdEdit = getEditor(); - - m_stacks->setCurrentWidget(mdEdit); - mdEdit->beginEdit(); - - // If editor is not init, we need to wait for it to init headers. - // Generally, beginEdit() will generate the headers. Wait is needed when - // highlight completion is going to re-generate the headers. - int nrRetry = 5; - while (header.m_index > -1 && m_outline.isEmpty() && nrRetry-- > 0) { - qDebug() << "wait another 100 ms for editor's headers ready"; - VUtils::sleepWait(100); - } - - scrollEditorToHeader(header); - - mdEdit->setFocus(); -} - -bool VMdTab::closeFile(bool p_forced) -{ - if (p_forced && m_isEditMode) { - // Discard buffer content - Q_ASSERT(m_editor); - m_editor->reloadFile(); - m_editor->endEdit(); - - showFileReadMode(); - } else { - readFile(); - } - - return !m_isEditMode; -} - -void VMdTab::editFile() -{ - if (m_isEditMode) { - return; - } - - showFileEditMode(); -} - -void VMdTab::readFile() -{ - if (!m_isEditMode) { - return; - } - - if (m_editor && isModified()) { - // Prompt to save the changes. - bool modifiable = m_file->isModifiable(); - int ret = VUtils::showMessage(QMessageBox::Information, tr("Information"), - tr("Note %2 has been modified.") - .arg(g_config->c_dataTextStyle).arg(m_file->getName()), - tr("Do you want to save your changes?"), - modifiable ? (QMessageBox::Save - | QMessageBox::Discard - | QMessageBox::Cancel) - : (QMessageBox::Discard - | QMessageBox::Cancel), - modifiable ? QMessageBox::Save - : QMessageBox::Cancel, - this); - switch (ret) { - case QMessageBox::Save: - if (!saveFile()) { - return; - } - - V_FALLTHROUGH; - - case QMessageBox::Discard: - m_editor->reloadFile(); - break; - - case QMessageBox::Cancel: - // Nothing to do if user cancel this action - return; - - default: - qWarning() << "wrong return value from QMessageBox:" << ret; - return; - } - } - - if (m_editor) { - m_editor->endEdit(); - } - - showFileReadMode(); -} - -bool VMdTab::saveFile() -{ - if (!m_isEditMode) { - return true; - } - - Q_ASSERT(m_editor); - - if (!isModified()) { - return true; - } - - QString filePath = m_file->fetchPath(); - - if (!m_file->isModifiable()) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Could not modify a read-only note %2.") - .arg(g_config->c_dataTextStyle).arg(filePath), - tr("Please save your changes to other notes manually."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - return false; - } - - bool ret = true; - // Make sure the file already exists. Temporary deal with cases when user delete or move - // a file. - if (!QFileInfo::exists(filePath)) { - qWarning() << filePath << "being written has been removed"; - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), tr("Fail to save note."), - tr("File %2 being written has been removed.") - .arg(g_config->c_dataTextStyle).arg(filePath), - QMessageBox::Ok, QMessageBox::Ok, this); - ret = false; - } else { - m_editor->saveFile(); - ret = m_file->save(); - if (!ret) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to save note."), - tr("Fail to write to disk when saving a note. Please try it again."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - m_editor->setModified(true); - } else { - m_fileDiverged = false; - m_checkFileChange = true; - } - } - - updateStatus(); - - return ret; -} - -bool VMdTab::isModified() const -{ - return (m_editor ? m_editor->isModified() : false) || m_fileDiverged; -} - -void VMdTab::saveAndRead() -{ - saveFile(); - readFile(); -} - -void VMdTab::discardAndRead() -{ - readFile(); -} - -void VMdTab::setupMarkdownViewer() -{ - m_webViewer = new VWebView(m_file, this); - connect(m_webViewer, &VWebView::editNote, - this, &VMdTab::editFile); - - VPreviewPage *page = new VPreviewPage(m_webViewer); - m_webViewer->setPage(page); - m_webViewer->setZoomFactor(g_config->getWebZoomFactor()); - - // Avoid white flash before loading content. - page->setBackgroundColor(Qt::transparent); - - m_document = new VDocument(m_file, m_webViewer); - - QWebChannel *channel = new QWebChannel(m_webViewer); - channel->registerObject(QStringLiteral("content"), m_document); - connect(m_document, &VDocument::tocChanged, - this, &VMdTab::updateOutlineFromHtml); - connect(m_document, SIGNAL(headerChanged(const QString &)), - this, SLOT(updateCurrentHeader(const QString &))); - connect(m_document, &VDocument::keyPressed, - this, &VMdTab::handleWebKeyPressed); - connect(m_document, &VDocument::logicsFinished, - this, [this]() { - if (m_ready & TabReady::ReadMode) { - // Recover header from edit mode. - scrollWebViewToHeader(m_headerFromEditMode); - m_headerFromEditMode.clear(); - return; - } - - m_ready |= TabReady::ReadMode; - - tabIsReady(TabReady::ReadMode); - }); - - page->setWebChannel(channel); - - m_webViewer->setHtml(VUtils::generateHtmlTemplate(m_mdConType, false), - m_file->getBaseUrl()); - - m_stacks->addWidget(m_webViewer); -} - -void VMdTab::setupMarkdownEditor() -{ - Q_ASSERT(!m_editor); - - m_editor = new VMdEditor(m_file, m_document, m_mdConType, this); - m_editor->setProperty("MainEditor", true); - connect(m_editor, &VMdEditor::headersChanged, - this, &VMdTab::updateOutlineFromHeaders); - connect(m_editor, SIGNAL(currentHeaderChanged(int)), - this, SLOT(updateCurrentHeader(int))); - connect(m_editor, &VMdEditor::statusChanged, - this, &VMdTab::updateStatus); - connect(m_editor, &VMdEditor::textChanged, - this, &VMdTab::updateStatus); - connect(m_editor, &VMdEditor::cursorPositionChanged, - this, &VMdTab::updateCursorStatus); - connect(g_mainWin, &VMainWindow::editorConfigUpdated, - m_editor, &VMdEditor::updateConfig); - connect(m_editor->object(), &VEditorObject::saveAndRead, - this, &VMdTab::saveAndRead); - connect(m_editor->object(), &VEditorObject::discardAndRead, - this, &VMdTab::discardAndRead); - connect(m_editor->object(), &VEditorObject::saveNote, - this, &VMdTab::saveFile); - connect(m_editor->object(), &VEditorObject::statusMessage, - this, &VEditTab::statusMessage); - connect(m_editor->object(), &VEditorObject::vimStatusUpdated, - this, &VEditTab::vimStatusUpdated); - connect(m_editor->object(), &VEditorObject::requestCloseFindReplaceDialog, - this, [this]() { - this->m_editArea->getFindReplaceDialog()->closeDialog(); - }); - connect(m_editor->object(), &VEditorObject::ready, - this, [this]() { - if (m_ready & TabReady::EditMode) { - return; - } - - m_ready |= TabReady::EditMode; - - tabIsReady(TabReady::EditMode); - }); - - enableHeadingSequence(m_enableHeadingSequence); - m_editor->reloadFile(); - m_stacks->addWidget(m_editor); -} - -void VMdTab::updateOutlineFromHtml(const QString &p_tocHtml) -{ - if (m_isEditMode) { - return; - } - - m_outline.clear(); - - if (m_outline.parseTableFromHtml(p_tocHtml)) { - m_outline.setFile(m_file); - m_outline.setType(VTableOfContentType::Anchor); - } - - m_currentHeader.reset(); - - emit outlineChanged(m_outline); -} - -void VMdTab::updateOutlineFromHeaders(const QVector &p_headers) -{ - if (!m_isEditMode) { - return; - } - - m_outline.update(m_file, - p_headers, - VTableOfContentType::BlockNumber); - - m_currentHeader.reset(); - - emit outlineChanged(m_outline); -} - -void VMdTab::scrollToHeader(const VHeaderPointer &p_header) -{ - if (m_outline.isMatched(p_header)) { - // Scroll only when @p_header is valid. - scrollToHeaderInternal(p_header); - } -} - -void VMdTab::updateCurrentHeader(const QString &p_anchor) -{ - if (m_isEditMode) { - return; - } - - // Find the index of the anchor in outline. - int idx = m_outline.indexOfItemByAnchor(p_anchor); - m_currentHeader.update(m_file, idx); - - emit currentHeaderChanged(m_currentHeader); -} - -void VMdTab::updateCurrentHeader(int p_blockNumber) -{ - if (!m_isEditMode) { - return; - } - - // Find the index of the block number in outline. - int idx = m_outline.indexOfItemByBlockNumber(p_blockNumber); - m_currentHeader.update(m_file, idx); - - emit currentHeaderChanged(m_currentHeader); -} - -void VMdTab::insertImage() -{ - if (!m_isEditMode) { - return; - } - - Q_ASSERT(m_editor); - m_editor->insertImage(); -} - -void VMdTab::insertLink() -{ - if (!m_isEditMode) { - return; - } - - Q_ASSERT(m_editor); - m_editor->insertLink(); -} - -void VMdTab::findText(const QString &p_text, uint p_options, bool p_peek, - bool p_forward) -{ - if (m_isEditMode) { - Q_ASSERT(m_editor); - if (p_peek) { - m_editor->peekText(p_text, p_options); - } else { - m_editor->findText(p_text, p_options, p_forward); - } - } else { - findTextInWebView(p_text, p_options, p_peek, p_forward); - } -} - -void VMdTab::replaceText(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext) -{ - if (m_isEditMode) { - Q_ASSERT(m_editor); - m_editor->replaceText(p_text, p_options, p_replaceText, p_findNext); - } -} - -void VMdTab::replaceTextAll(const QString &p_text, uint p_options, - const QString &p_replaceText) -{ - if (m_isEditMode) { - Q_ASSERT(m_editor); - m_editor->replaceTextAll(p_text, p_options, p_replaceText); - } -} - -void VMdTab::findTextInWebView(const QString &p_text, uint p_options, - bool /* p_peek */, bool p_forward) -{ - V_ASSERT(m_webViewer); - - QWebEnginePage::FindFlags flags; - if (p_options & FindOption::CaseSensitive) { - flags |= QWebEnginePage::FindCaseSensitively; - } - - if (!p_forward) { - flags |= QWebEnginePage::FindBackward; - } - - m_webViewer->findText(p_text, flags); -} - -QString VMdTab::getSelectedText() const -{ - if (m_isEditMode) { - Q_ASSERT(m_editor); - QTextCursor cursor = m_editor->textCursor(); - return cursor.selectedText(); - } else { - return m_webViewer->selectedText(); - } -} - -void VMdTab::clearSearchedWordHighlight() -{ - if (m_webViewer) { - m_webViewer->findText(""); - } - - if (m_editor) { - m_editor->clearSearchedWordHighlight(); - } -} - -void VMdTab::handleWebKeyPressed(int p_key, bool p_ctrl, bool /* p_shift */) -{ - V_ASSERT(m_webViewer); - - switch (p_key) { - // Esc - case 27: - m_editArea->getFindReplaceDialog()->closeDialog(); - break; - - // Dash - case 189: - if (p_ctrl) { - // Zoom out. - zoomWebPage(false); - } - break; - - // Equal - case 187: - if (p_ctrl) { - // Zoom in. - zoomWebPage(true); - } - break; - - // 0 - case 48: - if (p_ctrl) { - // Recover zoom. - m_webViewer->setZoomFactor(1); - } - break; - - default: - break; - } -} - -void VMdTab::zoom(bool p_zoomIn, qreal p_step) -{ - if (m_isEditMode) { - // TODO - } else { - zoomWebPage(p_zoomIn, p_step); - } -} - -void VMdTab::zoomWebPage(bool p_zoomIn, qreal p_step) -{ - V_ASSERT(m_webViewer); - - qreal curFactor = m_webViewer->zoomFactor(); - qreal newFactor = p_zoomIn ? curFactor + p_step : curFactor - p_step; - if (newFactor < c_webZoomFactorMin) { - newFactor = c_webZoomFactorMin; - } else if (newFactor > c_webZoomFactorMax) { - newFactor = c_webZoomFactorMax; - } - - m_webViewer->setZoomFactor(newFactor); -} - -VWebView *VMdTab::getWebViewer() const -{ - return m_webViewer; -} - -MarkdownConverterType VMdTab::getMarkdownConverterType() const -{ - return m_mdConType; -} - -void VMdTab::focusChild() -{ - m_stacks->currentWidget()->setFocus(); -} - -void VMdTab::requestUpdateVimStatus() -{ - if (m_editor) { - m_editor->requestUpdateVimStatus(); - } else { - emit vimStatusUpdated(NULL); - } -} - -VEditTabInfo VMdTab::fetchTabInfo(VEditTabInfo::InfoType p_type) const -{ - VEditTabInfo info = VEditTab::fetchTabInfo(p_type); - - if (m_editor) { - QTextCursor cursor = m_editor->textCursor(); - info.m_cursorBlockNumber = cursor.block().blockNumber(); - info.m_cursorPositionInBlock = cursor.positionInBlock(); - info.m_blockCount = m_editor->document()->blockCount(); - } - - info.m_headerIndex = m_currentHeader.m_index; - - return info; -} - -void VMdTab::decorateText(TextDecoration p_decoration, int p_level) -{ - if (m_editor) { - m_editor->decorateText(p_decoration, p_level); - } -} - -bool VMdTab::restoreFromTabInfo(const VEditTabInfo &p_info) -{ - if (p_info.m_editTab != this) { - return false; - } - - // Restore header. - VHeaderPointer header(m_file, p_info.m_headerIndex); - bool ret = scrollToHeaderInternal(header); - return ret; -} - -void VMdTab::restoreFromTabInfo() -{ - restoreFromTabInfo(m_infoToRestore); - - // Clear it anyway. - m_infoToRestore.clear(); -} - -void VMdTab::enableHeadingSequence(bool p_enabled) -{ - m_enableHeadingSequence = p_enabled; - - if (m_editor) { - VEditConfig &config = m_editor->getConfig(); - config.m_enableHeadingSequence = m_enableHeadingSequence; - } -} - -bool VMdTab::isHeadingSequenceEnabled() const -{ - return m_enableHeadingSequence; -} - -void VMdTab::evaluateMagicWords() -{ - if (isEditMode() && m_file->isModifiable()) { - getEditor()->evaluateMagicWords(); - } -} - -void VMdTab::applySnippet(const VSnippet *p_snippet) -{ - Q_ASSERT(p_snippet); - - if (isEditMode() - && m_file->isModifiable() - && p_snippet->getType() == VSnippet::Type::PlainText) { - Q_ASSERT(m_editor); - QTextCursor cursor = m_editor->textCursor(); - bool changed = p_snippet->apply(cursor); - if (changed) { - m_editor->setTextCursor(cursor); - - m_editor->setVimMode(VimMode::Insert); - - g_mainWin->showStatusMessage(tr("Snippet applied")); - - focusTab(); - } - } else { - g_mainWin->showStatusMessage(tr("Snippet %1 is not applicable").arg(p_snippet->getName())); - } -} - -void VMdTab::applySnippet() -{ - if (!isEditMode() || !m_file->isModifiable()) { - g_mainWin->showStatusMessage(tr("Snippets are not applicable")); - return; - } - - QPoint pos(m_editor->cursorRect().bottomRight()); - QMenu menu(this); - VInsertSelector *sel = prepareSnippetSelector(&menu); - if (!sel) { - g_mainWin->showStatusMessage(tr("No available snippets defined with shortcuts")); - return; - } - - QWidgetAction *act = new QWidgetAction(&menu); - act->setDefaultWidget(sel); - connect(sel, &VInsertSelector::accepted, - this, [this, &menu]() { - QKeyEvent *escEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Escape, - Qt::NoModifier); - QCoreApplication::postEvent(&menu, escEvent); - }); - - menu.addAction(act); - - menu.exec(m_editor->mapToGlobal(pos)); - - QString chosenItem = sel->getClickedItem(); - if (!chosenItem.isEmpty()) { - const VSnippet *snip = g_mainWin->getSnippetList()->getSnippet(chosenItem); - if (snip) { - applySnippet(snip); - } - } -} - -static bool selectorItemCmp(const VInsertSelectorItem &p_a, const VInsertSelectorItem &p_b) -{ - if (p_a.m_shortcut < p_b.m_shortcut) { - return true; - } - - return false; -} - -VInsertSelector *VMdTab::prepareSnippetSelector(QWidget *p_parent) -{ - auto snippets = g_mainWin->getSnippetList()->getSnippets(); - QVector items; - for (auto const & snip : snippets) { - if (!snip.getShortcut().isNull()) { - items.push_back(VInsertSelectorItem(snip.getName(), - snip.getName(), - snip.getShortcut())); - } - } - - if (items.isEmpty()) { - return NULL; - } - - // Sort items by shortcut. - std::sort(items.begin(), items.end(), selectorItemCmp); - - VInsertSelector *sel = new VInsertSelector(7, items, p_parent); - return sel; -} - -void VMdTab::reload() -{ - if (m_isEditMode) { - m_editor->reloadFile(); - m_editor->endEdit(); - m_editor->beginEdit(); - updateStatus(); - } else { - if (m_editor) { - m_editor->reloadFile(); - } - - showFileReadMode(); - } -} - -void VMdTab::tabIsReady(TabReady p_mode) -{ - bool isCurrentMode = (m_isEditMode && p_mode == TabReady::EditMode) - || (!m_isEditMode && p_mode == TabReady::ReadMode); - - if (isCurrentMode) { - restoreFromTabInfo(); - - if (m_enableBackupFile - && !m_backupFileChecked - && m_file->isModifiable()) { - if (!checkPreviousBackupFile()) { - return; - } - } - } - - if (m_enableBackupFile - && m_file->isModifiable() - && p_mode == TabReady::EditMode) { - // contentsChanged will be emitted even the content is not changed. - connect(m_editor->document(), &QTextDocument::contentsChange, - this, [this]() { - if (m_isEditMode) { - m_backupTimer->stop(); - m_backupTimer->start(); - } - }); - } -} - -void VMdTab::writeBackupFile() -{ - Q_ASSERT(m_enableBackupFile && m_file->isModifiable()); - m_file->writeBackupFile(m_editor->getContent()); -} - -bool VMdTab::checkPreviousBackupFile() -{ - m_backupFileChecked = true; - - QString preFile = m_file->backupFileOfPreviousSession(); - if (preFile.isEmpty()) { - return true; - } - - QMessageBox box(QMessageBox::Warning, - tr("Backup File Found"), - tr("Found backup file %2 " - "when opening note %3.") - .arg(g_config->c_dataTextStyle) - .arg(preFile) - .arg(m_file->fetchPath()), - QMessageBox::NoButton, - this); - QString backupContent = m_file->readBackupFile(preFile); - QString info = tr("VNote may crash while editing this note before.
    " - "Please choose to recover from the backup file or delete it.

    " - "Note file last modified: %2
    " - "Backup file last modified: %3
    " - "Content comparison: %4") - .arg(g_config->c_dataTextStyle) - .arg(VUtils::displayDateTime(QFileInfo(m_file->fetchPath()).lastModified())) - .arg(VUtils::displayDateTime(QFileInfo(preFile).lastModified())) - .arg(m_file->getContent() == backupContent ? tr("Identical") - : tr("Different")); - box.setInformativeText(info); - QPushButton *recoverBtn = box.addButton(tr("Recover From Backup File"), QMessageBox::YesRole); - box.addButton(tr("Discard Backup File"), QMessageBox::NoRole); - QPushButton *cancelBtn = box.addButton(tr("Cancel"), QMessageBox::RejectRole); - - box.setDefaultButton(cancelBtn); - box.setTextInteractionFlags(Qt::TextSelectableByMouse); - - box.exec(); - QAbstractButton *btn = box.clickedButton(); - if (btn == cancelBtn || !btn) { - // Close current tab. - emit closeRequested(this); - return false; - } else if (btn == recoverBtn) { - // Load content from the backup file. - if (!m_isEditMode) { - showFileEditMode(); - } - - Q_ASSERT(m_editor); - m_editor->setContent(backupContent, true); - - updateStatus(); - } - - VUtils::deleteFile(preFile); - - return true; -} - -void VMdTab::updateCursorStatus() -{ - emit statusUpdated(fetchTabInfo(VEditTabInfo::InfoType::Cursor)); -} - -void VMdTab::handleFileOrDirectoryChange(bool p_isFile, UpdateAction p_act) -{ - // Reload the web view with new base URL. - m_headerFromEditMode = m_currentHeader; - m_webViewer->setHtml(VUtils::generateHtmlTemplate(m_mdConType, false), - m_file->getBaseUrl()); - - if (m_editor) { - m_editor->updateInitAndInsertedImages(p_isFile, p_act); - - // Refresh the previewed images in edit mode. - m_editor->refreshPreview(); - } -} diff --git a/src/vmdtab.h b/src/vmdtab.h deleted file mode 100644 index 755761ac..00000000 --- a/src/vmdtab.h +++ /dev/null @@ -1,221 +0,0 @@ -#ifndef VMDTAB_H -#define VMDTAB_H - -#include -#include -#include "vedittab.h" -#include "vconstants.h" -#include "vmarkdownconverter.h" -#include "vconfigmanager.h" - -class VWebView; -class QStackedLayout; -class VDocument; -class VMdEditor; -class VInsertSelector; -class QTimer; - -class VMdTab : public VEditTab -{ - Q_OBJECT - -public: - VMdTab(VFile *p_file, VEditArea *p_editArea, OpenFileMode p_mode, QWidget *p_parent = 0); - - // Close current tab. - // @p_forced: if true, discard the changes. - bool closeFile(bool p_forced) Q_DECL_OVERRIDE; - - // Enter read mode. - // Will prompt user to save the changes. - void readFile() Q_DECL_OVERRIDE; - - // Save file. - bool saveFile() Q_DECL_OVERRIDE; - - bool isModified() const Q_DECL_OVERRIDE; - - // Scroll to @p_header. - void scrollToHeader(const VHeaderPointer &p_header) Q_DECL_OVERRIDE; - - void insertImage() Q_DECL_OVERRIDE; - - void insertLink() Q_DECL_OVERRIDE; - - // Search @p_text in current note. - void findText(const QString &p_text, uint p_options, bool p_peek, - bool p_forward = true) Q_DECL_OVERRIDE; - - // Replace @p_text with @p_replaceText in current note. - void replaceText(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext) Q_DECL_OVERRIDE; - - void replaceTextAll(const QString &p_text, uint p_options, - const QString &p_replaceText) Q_DECL_OVERRIDE; - - QString getSelectedText() const Q_DECL_OVERRIDE; - - void clearSearchedWordHighlight() Q_DECL_OVERRIDE; - - VWebView *getWebViewer() const; - - VMdEditor *getEditor() const; - - MarkdownConverterType getMarkdownConverterType() const; - - void requestUpdateVimStatus() Q_DECL_OVERRIDE; - - // Insert decoration markers or decorate selected text. - void decorateText(TextDecoration p_decoration, int p_level = -1) Q_DECL_OVERRIDE; - - // Create a filled VEditTabInfo. - VEditTabInfo fetchTabInfo(VEditTabInfo::InfoType p_type = VEditTabInfo::InfoType::All) const Q_DECL_OVERRIDE; - - // Enable or disable heading sequence. - void enableHeadingSequence(bool p_enabled); - - bool isHeadingSequenceEnabled() const; - - // Evaluate magic words. - void evaluateMagicWords() Q_DECL_OVERRIDE; - - void applySnippet(const VSnippet *p_snippet) Q_DECL_OVERRIDE; - - void applySnippet() Q_DECL_OVERRIDE; - - void reload() Q_DECL_OVERRIDE; - - void handleFileOrDirectoryChange(bool p_isFile, UpdateAction p_act) Q_DECL_OVERRIDE; - -public slots: - // Enter edit mode. - void editFile() Q_DECL_OVERRIDE; - -protected: - void writeBackupFile() Q_DECL_OVERRIDE; - -private slots: - // Update m_outline according to @p_tocHtml for read mode. - void updateOutlineFromHtml(const QString &p_tocHtml); - - // Update m_outline accroding to @p_headers for edit mode. - void updateOutlineFromHeaders(const QVector &p_headers); - - // Web viewer requests to update current header. - // @p_anchor is the anchor of the header, like "toc_1". - void updateCurrentHeader(const QString &p_anchor); - - // Editor requests to update current header. - void updateCurrentHeader(int p_blockNumber); - - // Handle key press event in Web view. - void handleWebKeyPressed(int p_key, bool p_ctrl, bool p_shift); - - // m_editor requests to save changes and enter read mode. - void saveAndRead(); - - // m_editor requests to discard changes and enter read mode. - void discardAndRead(); - - // Restore from m_infoToRestore. - void restoreFromTabInfo(); - -private: - enum TabReady { None = 0, ReadMode = 0x1, EditMode = 0x2 }; - - // Setup UI. - void setupUI(); - - // Show the file content in read mode. - void showFileReadMode(); - - // Show the file content in edit mode. - void showFileEditMode(); - - // Setup Markdown viewer. - void setupMarkdownViewer(); - - // Setup Markdown editor. - void setupMarkdownEditor(); - - // Use VMarkdownConverter (hoedown) to generate the Web view. - void viewWebByConverter(); - - // Scroll Web view to given header. - // Return true if scroll was made. - bool scrollWebViewToHeader(const VHeaderPointer &p_header); - - bool scrollEditorToHeader(const VHeaderPointer &p_header); - - // Scroll web/editor to given header. - // Return true if scroll was made. - bool scrollToHeaderInternal(const VHeaderPointer &p_header); - - // Search text in Web view. - void findTextInWebView(const QString &p_text, uint p_options, bool p_peek, - bool p_forward); - - // Called to zoom in/out content. - void zoom(bool p_zoomIn, qreal p_step = 0.25) Q_DECL_OVERRIDE; - - // Zoom Web View. - void zoomWebPage(bool p_zoomIn, qreal p_step = 0.25); - - // Focus the proper child widget. - void focusChild() Q_DECL_OVERRIDE; - - // Get the markdown editor. If not init yet, init and return it. - VMdEditor *getEditor(); - - // Restore from @p_fino. - // Return true if succeed. - bool restoreFromTabInfo(const VEditTabInfo &p_info) Q_DECL_OVERRIDE; - - // Prepare insert selector with snippets. - VInsertSelector *prepareSnippetSelector(QWidget *p_parent = nullptr); - - // Called once read or edit mode is ready. - void tabIsReady(TabReady p_mode); - - // Check if there exists backup file from previous session. - // Return true if we could continue. - bool checkPreviousBackupFile(); - - // updateStatus() with only cursor position information. - void updateCursorStatus(); - - VMdEditor *m_editor; - VWebView *m_webViewer; - VDocument *m_document; - MarkdownConverterType m_mdConType; - - // Whether heading sequence is enabled. - bool m_enableHeadingSequence; - - QStackedLayout *m_stacks; - - // Timer to write backup file when content has been changed. - QTimer *m_backupTimer; - - bool m_backupFileChecked; - - // Used to scroll to the header of edit mode in read mode. - VHeaderPointer m_headerFromEditMode; -}; - -inline VMdEditor *VMdTab::getEditor() -{ - if (m_editor) { - return m_editor; - } else { - setupMarkdownEditor(); - return m_editor; - } -} - -inline VMdEditor *VMdTab::getEditor() const -{ - return m_editor; -} - -#endif // VMDTAB_H diff --git a/src/vnavigationmode.cpp b/src/vnavigationmode.cpp deleted file mode 100644 index 25902445..00000000 --- a/src/vnavigationmode.cpp +++ /dev/null @@ -1,211 +0,0 @@ -#include "vnavigationmode.h" - -#include -#include -#include -#include -#include - -#include "vnote.h" -#include "utils/vutils.h" - -extern VNote *g_vnote; - -VNavigationMode::VNavigationMode() -{ -} - -VNavigationMode::~VNavigationMode() -{ -} - -void VNavigationMode::registerNavigation(QChar p_majorKey) -{ - m_majorKey = p_majorKey; - Q_ASSERT(m_keyMap.empty()); - Q_ASSERT(m_naviLabels.empty()); -} - -void VNavigationMode::hideNavigation() -{ - clearNavigation(); -} - -void VNavigationMode::showNavigation(QListWidget *p_widget) -{ - clearNavigation(); - - if (!p_widget->isVisible()) { - return; - } - - // Generate labels for visible items. - auto items = getVisibleItems(p_widget); - for (int i = 0; i < 26 && i < items.size(); ++i) { - QChar key('a' + i); - m_keyMap[key] = items[i]; - - QString str = QString(m_majorKey) + key; - QLabel *label = new QLabel(str, p_widget); - label->setStyleSheet(g_vnote->getNavigationLabelStyle(str)); - label->show(); - QRect rect = p_widget->visualItemRect(items[i]); - // Display the label at the end to show the file name. - // Fix: take the vertical scrollbar into account. - int extraWidth = label->width() + 2; - QScrollBar *vbar = p_widget->verticalScrollBar(); - if (vbar && vbar->minimum() != vbar->maximum()) { - extraWidth += vbar->width(); - } - - label->move(rect.x() + p_widget->rect().width() - extraWidth, - rect.y()); - - m_naviLabels.append(label); - } -} - -QList VNavigationMode::getVisibleItems(const QListWidget *p_widget) const -{ - QList items; - for (int i = 0; i < p_widget->count(); ++i) { - QListWidgetItem *item = p_widget->item(i); - if (!item->isHidden()) { - items.append(item); - } - } - - return items; -} - -static QList getVisibleChildItems(const QTreeWidgetItem *p_item) -{ - QList items; - if (p_item && !p_item->isHidden() && p_item->isExpanded()) { - for (int i = 0; i < p_item->childCount(); ++i) { - QTreeWidgetItem *child = p_item->child(i); - if (!child->isHidden()) { - items.append(child); - if (child->isExpanded()) { - items.append(getVisibleChildItems(child)); - } - } - } - } - - return items; -} - -QList VNavigationMode::getVisibleItems(const QTreeWidget *p_widget) const -{ - QList items; - for (int i = 0; i < p_widget->topLevelItemCount(); ++i) { - QTreeWidgetItem *item = p_widget->topLevelItem(i); - if (!item->isHidden()) { - items.append(item); - if (item->isExpanded()) { - items.append(getVisibleChildItems(item)); - } - } - } - - return items; -} - -bool VNavigationMode::handleKeyNavigation(QListWidget *p_widget, - bool &p_secondKey, - int p_key, - bool &p_succeed) -{ - bool ret = false; - p_succeed = false; - QChar keyChar = VUtils::keyToChar(p_key); - if (p_secondKey && !keyChar.isNull()) { - p_secondKey = false; - p_succeed = true; - ret = true; - auto it = m_keyMap.find(keyChar); - if (it != m_keyMap.end()) { - p_widget->setCurrentItem(static_cast(it.value()), - QItemSelectionModel::ClearAndSelect); - p_widget->setFocus(); - } - } else if (keyChar == m_majorKey) { - // Major key pressed. - // Need second key if m_keyMap is not empty. - if (m_keyMap.isEmpty()) { - p_succeed = true; - } else { - p_secondKey = true; - } - - ret = true; - } - - return ret; -} - -void VNavigationMode::showNavigation(QTreeWidget *p_widget) -{ - clearNavigation(); - - if (!p_widget->isVisible()) { - return; - } - - // Generate labels for visible items. - auto items = getVisibleItems(p_widget); - for (int i = 0; i < 26 && i < items.size(); ++i) { - QChar key('a' + i); - m_keyMap[key] = items[i]; - - QString str = QString(m_majorKey) + key; - QLabel *label = new QLabel(str, p_widget); - label->setStyleSheet(g_vnote->getNavigationLabelStyle(str)); - label->move(p_widget->visualItemRect(items[i]).topLeft()); - label->show(); - m_naviLabels.append(label); - } -} - -void VNavigationMode::clearNavigation() -{ - m_keyMap.clear(); - for (auto label : m_naviLabels) { - delete label; - } - - m_naviLabels.clear(); -} - -bool VNavigationMode::handleKeyNavigation(QTreeWidget *p_widget, - bool &p_secondKey, - int p_key, - bool &p_succeed) -{ - bool ret = false; - p_succeed = false; - QChar keyChar = VUtils::keyToChar(p_key); - if (p_secondKey && !keyChar.isNull()) { - p_secondKey = false; - p_succeed = true; - ret = true; - auto it = m_keyMap.find(keyChar); - if (it != m_keyMap.end()) { - p_widget->setCurrentItem(static_cast(it.value())); - p_widget->setFocus(); - } - } else if (keyChar == m_majorKey) { - // Major key pressed. - // Need second key if m_keyMap is not empty. - if (m_keyMap.isEmpty()) { - p_succeed = true; - } else { - p_secondKey = true; - } - - ret = true; - } - - return ret; -} diff --git a/src/vnavigationmode.h b/src/vnavigationmode.h deleted file mode 100644 index a1a45376..00000000 --- a/src/vnavigationmode.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef VNAVIGATIONMODE_H -#define VNAVIGATIONMODE_H - -#include -#include -#include -#include - -class QLabel; -class QListWidget; -class QListWidgetItem; -class QTreeWidget; -class QTreeWidgetItem; - - -// Interface class for Navigation Mode in Captain Mode. -class VNavigationMode -{ -public: - VNavigationMode(); - - virtual ~VNavigationMode(); - - virtual void registerNavigation(QChar p_majorKey); - - virtual void showNavigation() = 0; - - virtual void hideNavigation(); - - // Return true if this object could consume p_key. - // p_succeed indicates whether the keys hit a target successfully. - virtual bool handleKeyNavigation(int p_key, bool &p_succeed) = 0; - -protected: - void clearNavigation(); - - void showNavigation(QListWidget *p_widget); - - void showNavigation(QTreeWidget *p_widget); - - bool handleKeyNavigation(QListWidget *p_widget, - bool &p_secondKey, - int p_key, - bool &p_succeed); - - bool handleKeyNavigation(QTreeWidget *p_widget, - bool &p_secondKey, - int p_key, - bool &p_succeed); - - QChar m_majorKey; - - // Map second key to item. - QMap m_keyMap; - - QVector m_naviLabels; - -private: - QList getVisibleItems(const QListWidget *p_widget) const; - - QList getVisibleItems(const QTreeWidget *p_widget) const; -}; - -#endif // VNAVIGATIONMODE_H diff --git a/src/vnofocusitemdelegate.cpp b/src/vnofocusitemdelegate.cpp deleted file mode 100644 index 2ea6c008..00000000 --- a/src/vnofocusitemdelegate.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "vnofocusitemdelegate.h" - -VNoFocusItemDelegate::VNoFocusItemDelegate(QWidget *parent) - : QStyledItemDelegate(parent) -{ - -} - -void VNoFocusItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const -{ - QStyleOptionViewItem itemOp(option); - if (itemOp.state & QStyle::State_HasFocus) { - itemOp.state ^= QStyle::State_HasFocus; - } - QStyledItemDelegate::paint(painter, itemOp, index); -} diff --git a/src/vnofocusitemdelegate.h b/src/vnofocusitemdelegate.h deleted file mode 100644 index 794db0ab..00000000 --- a/src/vnofocusitemdelegate.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef VNOFOCUSITEMDELEGATE_H -#define VNOFOCUSITEMDELEGATE_H - -#include - -class VNoFocusItemDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - explicit VNoFocusItemDelegate(QWidget *parent = 0); - void paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const Q_DECL_OVERRIDE; -}; - -#endif // VNOFOCUSITEMDELEGATE_H diff --git a/src/vnote.cpp b/src/vnote.cpp deleted file mode 100644 index 62eb1847..00000000 --- a/src/vnote.cpp +++ /dev/null @@ -1,279 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "vnote.h" -#include "utils/vutils.h" -#include "vconfigmanager.h" -#include "vmainwindow.h" -#include "vorphanfile.h" -#include "vnotefile.h" -#include "vpalette.h" - -extern VConfigManager *g_config; - -extern VPalette *g_palette; - -// Meta word manager. -VMetaWordManager *g_mwMgr; - -QString VNote::s_markdownTemplate; -QString VNote::s_markdownTemplatePDF; - -const QString VNote::c_hoedownJsFile = ":/resources/hoedown.js"; - -const QString VNote::c_markedJsFile = ":/resources/marked.js"; -const QString VNote::c_markedExtraFile = ":/utils/marked/marked.min.js"; - -const QString VNote::c_markdownitJsFile = ":/resources/markdown-it.js"; -const QString VNote::c_markdownitExtraFile = ":/utils/markdown-it/markdown-it.min.js"; -const QString VNote::c_markdownitAnchorExtraFile = ":/utils/markdown-it/markdown-it-headinganchor.js"; -const QString VNote::c_markdownitTaskListExtraFile = ":/utils/markdown-it/markdown-it-task-lists.min.js"; -const QString VNote::c_markdownitSubExtraFile = ":/utils/markdown-it/markdown-it-sub.min.js"; -const QString VNote::c_markdownitSupExtraFile = ":/utils/markdown-it/markdown-it-sup.min.js"; -const QString VNote::c_markdownitFootnoteExtraFile = ":/utils/markdown-it/markdown-it-footnote.min.js"; - -const QString VNote::c_showdownJsFile = ":/resources/showdown.js"; -const QString VNote::c_showdownExtraFile = ":/utils/showdown/showdown.min.js"; -const QString VNote::c_showdownAnchorExtraFile = ":/utils/showdown/showdown-headinganchor.js"; - -const QString VNote::c_mermaidApiJsFile = ":/utils/mermaid/mermaidAPI.min.js"; -const QString VNote::c_mermaidCssFile = ":/utils/mermaid/mermaid.css"; -const QString VNote::c_mermaidDarkCssFile = ":/utils/mermaid/mermaid.dark.css"; -const QString VNote::c_mermaidForestCssFile = ":/utils/mermaid/mermaid.forest.css"; - -const QString VNote::c_flowchartJsFile = ":/utils/flowchart.js/flowchart.min.js"; -const QString VNote::c_raphaelJsFile = ":/utils/flowchart.js/raphael.min.js"; - -const QString VNote::c_highlightjsLineNumberExtraFile = ":/utils/highlightjs/highlightjs-line-numbers.min.js"; - -const QString VNote::c_shortcutsDocFile_en = ":/resources/docs/shortcuts_en.md"; -const QString VNote::c_shortcutsDocFile_zh = ":/resources/docs/shortcuts_zh.md"; - -const QString VNote::c_markdownGuideDocFile_en = ":/resources/docs/markdown_guide_en.md"; -const QString VNote::c_markdownGuideDocFile_zh = ":/resources/docs/markdown_guide_zh.md"; - -VNote::VNote(QObject *parent) - : QObject(parent) -{ - initTemplate(); - - g_config->getNotebooks(m_notebooks, this); - - m_metaWordMgr.init(); - - g_mwMgr = &m_metaWordMgr; -} - -void VNote::initTemplate() -{ - if (s_markdownTemplate.isEmpty()) { - updateTemplate(); - } -} - -void VNote::updateTemplate() -{ - const QString c_markdownTemplatePath(":/resources/markdown_template.html"); - - // Get background color - QString rgb; - const QString &curRenderBg = g_config->getCurRenderBackgroundColor(); - const QVector &predefinedColors = g_config->getPredefinedColors(); - if (curRenderBg != "System") { - for (int i = 0; i < predefinedColors.size(); ++i) { - if (predefinedColors[i].name == curRenderBg) { - rgb = predefinedColors[i].rgb; - break; - } - } - } - - QString cssStyle; - if (!rgb.isEmpty()) { - cssStyle += "body { background-color: #" + rgb + " !important; }\n"; - } - - if (g_config->getEnableImageConstraint()) { - // Constain the image width. - cssStyle += "img { max-width: 100% !important; height: auto !important; }\n"; - } - - const QString styleHolder(""); - const QString cssHolder("CSS_PLACE_HOLDER"); - const QString codeBlockCssHolder("HIGHLIGHTJS_CSS_PLACE_HOLDER"); - - s_markdownTemplate = VUtils::readFileFromDisk(c_markdownTemplatePath); - g_palette->fillStyle(s_markdownTemplate); - - // Must replace the code block holder first. - s_markdownTemplate.replace(codeBlockCssHolder, g_config->getCodeBlockCssStyleUrl()); - s_markdownTemplate.replace(cssHolder, g_config->getCssStyleUrl()); - - s_markdownTemplatePDF = s_markdownTemplate; - - if (!cssStyle.isEmpty()) { - s_markdownTemplate.replace(styleHolder, cssStyle); - } - - // Shoudl not display scrollbar in PDF. - cssStyle += "pre { white-space: pre-wrap !important; " - "word-break: break-all !important; }\n"; - if (!g_config->getEnableImageConstraint()) { - // Constain the image width by force in PDF, otherwise, the PDF will - // be cut off. - cssStyle += "img { max-width: 100% !important; height: auto !important; }\n"; - } - - s_markdownTemplatePDF.replace(styleHolder, cssStyle); -} - -const QVector &VNote::getNotebooks() const -{ - return m_notebooks; -} - -QVector &VNote::getNotebooks() -{ - return m_notebooks; -} - -QString VNote::getNavigationLabelStyle(const QString &p_str) const -{ - static int lastLen = -1; - static int pxWidth = 24; - const int fontPt = 15; - - QString fontFamily = getMonospacedFont(); - - if (p_str.size() != lastLen) { - QFont font(fontFamily, fontPt); - font.setBold(true); - QFontMetrics fm(font); - pxWidth = fm.width(p_str); - lastLen = p_str.size(); - } - - QColor bg(g_palette->color("navigation_label_bg")); - bg.setAlpha(200); - - return QString("background-color: %1;" - "color: %2;" - "font-size: %3pt;" - "font: bold;" - "font-family: %4;" - "border-radius: 3px;" - "min-width: %5px;" - "max-width: %5px;") - .arg(bg.name(QColor::HexArgb)) - .arg(g_palette->color("navigation_label_fg")) - .arg(fontPt) - .arg(fontFamily) - .arg(pxWidth); -} - -const QString &VNote::getMonospacedFont() const -{ - static QString font; - if (font.isNull()) { - QStringList candidates; - candidates << "Consolas" << "Monaco" << "Andale Mono" << "Monospace" << "Courier New"; - QStringList availFamilies = QFontDatabase().families(); - - for (int i = 0; i < candidates.size(); ++i) { - QString family = candidates[i].trimmed().toLower(); - for (int j = 0; j < availFamilies.size(); ++j) { - QString availFamily = availFamilies[j]; - availFamily.remove(QRegExp("\\[.*\\]")); - if (family == availFamily.trimmed().toLower()) { - font = availFamily; - return font; - } - } - } - - // Fallback to current font. - font = QFont().family(); - } - return font; -} - -VOrphanFile *VNote::getOrphanFile(const QString &p_path, bool p_modifiable, bool p_systemFile) -{ - if (p_path.isEmpty()) { - return NULL; - } - - QString path = QDir::cleanPath(p_path); - // See if the file has already been opened before. - for (auto const &file : m_externalFiles) { - if (VUtils::equalPath(QDir::cleanPath(file->fetchPath()), path)) { - Q_ASSERT(file->isModifiable() == p_modifiable); - Q_ASSERT(file->isSystemFile() == p_systemFile); - return file; - } - } - - for (int i = 0; i < m_externalFiles.size(); ++i) { - VOrphanFile *file = m_externalFiles[i]; - if (!file->isOpened()) { - qDebug() << "release orphan file" << file; - m_externalFiles.removeAt(i); - delete file; - --i; - } - } - - // Create a VOrphanFile for path. - VOrphanFile *file = new VOrphanFile(this, path, p_modifiable, p_systemFile); - m_externalFiles.append(file); - return file; -} - -VNoteFile *VNote::getInternalFile(const QString &p_path) -{ - VNoteFile *file = NULL; - for (auto & nb : m_notebooks) { - file = nb->tryLoadFile(p_path); - if (file) { - break; - } - } - - return file; -} - -VFile *VNote::getFile(const QString &p_path) -{ - VFile *file = getInternalFile(p_path); - if (!file) { - QFileInfo fi(p_path); - if (fi.isNativePath()) { - file = getOrphanFile(p_path, true, false); - } else { - // File in Qt resource system. - file = getOrphanFile(p_path, false, true); - } - } - - return file; -} - -VDirectory *VNote::getInternalDirectory(const QString &p_path) -{ - VDirectory *dir = NULL; - for (auto & nb : m_notebooks) { - dir = nb->tryLoadDirectory(p_path); - if (dir) { - break; - } - } - - return dir; - -} diff --git a/src/vnote.desktop b/src/vnote.desktop deleted file mode 100644 index 9bc683c4..00000000 --- a/src/vnote.desktop +++ /dev/null @@ -1,11 +0,0 @@ -[Desktop Entry] -Type=Application -Version=1.0 -Name=VNote -GenericName=Markdown Note -Comment=Note-taking application for pleasant Markdown -Icon=vnote -Terminal=false -Exec=VNote %F -MimeType=text/markdown; -Categories=Qt;Utility;TextEditor;Office; diff --git a/src/vnote.h b/src/vnote.h deleted file mode 100644 index b3a4d890..00000000 --- a/src/vnote.h +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef VNOTE_H -#define VNOTE_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "vnotebook.h" -#include "vconstants.h" -#include "utils/vmetawordmanager.h" - -class VOrphanFile; -class VNoteFile; - - -class VNote : public QObject -{ - Q_OBJECT -public: - VNote(QObject *parent = 0); - - const QVector &getNotebooks() const; - QVector &getNotebooks(); - - void initTemplate(); - - static QString s_markdownTemplate; - static QString s_markdownTemplatePDF; - - // Hoedown - static const QString c_hoedownJsFile; - - // Marked - static const QString c_markedJsFile; - static const QString c_markedExtraFile; - - // Markdown-it - static const QString c_markdownitJsFile; - static const QString c_markdownitExtraFile; - static const QString c_markdownitAnchorExtraFile; - static const QString c_markdownitTaskListExtraFile; - static const QString c_markdownitSubExtraFile; - static const QString c_markdownitSupExtraFile; - static const QString c_markdownitFootnoteExtraFile; - - // Showdown - static const QString c_showdownJsFile; - static const QString c_showdownExtraFile; - static const QString c_showdownAnchorExtraFile; - - // Mermaid - static const QString c_mermaidApiJsFile; - static const QString c_mermaidCssFile; - static const QString c_mermaidDarkCssFile; - static const QString c_mermaidForestCssFile; - - // flowchart.js - static const QString c_flowchartJsFile; - static const QString c_raphaelJsFile; - - // Highlight.js line number plugin - static const QString c_highlightjsLineNumberExtraFile; - - static const QString c_shortcutsDocFile_en; - static const QString c_shortcutsDocFile_zh; - - static const QString c_markdownGuideDocFile_en; - static const QString c_markdownGuideDocFile_zh; - - // Get the label style in Navigation mode. - QString getNavigationLabelStyle(const QString &p_str) const; - - // Given the path of a file, first try to open it as note file, - // then try to open it as orphan file. - VFile *getFile(const QString &p_path); - - // Given the path of an external file, create a VOrphanFile struct. - VOrphanFile *getOrphanFile(const QString &p_path, - bool p_modifiable, - bool p_systemFile = false); - - // Given the path of a file, try to find it in all notebooks. - // Returns a VNoteFile struct if it is a note in one notebook. - // Otherwise, returns NULL. - VNoteFile *getInternalFile(const QString &p_path); - - // Given the path of a folder, try to find it in all notebooks. - // Returns a VDirectory struct if it is a folder in one notebook. - // Otherwise, returns NULL. - VDirectory *getInternalDirectory(const QString &p_path); - -public slots: - void updateTemplate(); - -private: - const QString &getMonospacedFont() const; - - // Maintain all the notebooks. Other holder should use QPointer. - QVector m_notebooks; - - VMetaWordManager m_metaWordMgr; - - // Hold all external file: Orphan File. - // Need to clean up periodly. - QList m_externalFiles; -}; - -#endif // VNOTE_H diff --git a/src/vnote.qrc b/src/vnote.qrc deleted file mode 100644 index 67dd17c5..00000000 --- a/src/vnote.qrc +++ /dev/null @@ -1,222 +0,0 @@ - - - resources/welcome.html - resources/qwebchannel.js - utils/marked/marked.min.js - utils/highlightjs/highlight.pack.js - resources/vnote.ini - resources/icons/create_note_tb.svg - resources/icons/save_note.svg - resources/icons/edit_note.svg - resources/icons/save_exit.svg - resources/icons/discard_exit.svg - resources/icons/create_note.svg - resources/icons/create_notebook.svg - resources/icons/create_rootdir.svg - resources/icons/delete_dir.svg - resources/icons/delete_note.svg - resources/icons/delete_notebook.svg - resources/icons/note_info.svg - resources/icons/dir_info.svg - resources/icons/notebook_info.svg - resources/icons/expand.svg - resources/icons/two_panels.svg - resources/icons/one_panel.svg - resources/icons/split_window.svg - resources/icons/corner_menu.svg - resources/icons/remove_split.svg - resources/icons/corner_tablist.svg - resources/icons/outline.svg - resources/icons/create_rootdir_tb.svg - resources/icons/vnote.svg - resources/icons/vnote.ico - resources/icons/note_info_tb.svg - resources/icons/delete_note_tb.svg - resources/icons/copy.svg - resources/icons/cut.svg - resources/icons/paste.svg - resources/icons/dir_item.svg - resources/icons/notebook_item.svg - resources/icons/vnote.png - resources/icons/insert_image.svg - resources/icons/import_note.svg - resources/icons/editing.svg - resources/icons/reading.svg - resources/icons/locate_note.svg - resources/icons/move_tab_left.svg - resources/icons/move_tab_right.svg - resources/icons/corner_menu_cur.svg - resources/icons/corner_tablist_cur.svg - resources/icons/close.svg - resources/icons/find_replace.svg - resources/icons/search_wrap.svg - resources/icons/settings.svg - resources/markdown_template.html - resources/markdown_template.js - resources/hoedown.js - resources/marked.js - resources/markdown-it.js - utils/markdown-it/markdown-it.min.js - utils/markdown-it/markdown-it-headinganchor.js - utils/markdown-it/markdown-it-task-lists.min.js - utils/mermaid/mermaid.css - utils/mermaid/mermaid.dark.css - utils/mermaid/mermaid.forest.css - utils/mermaid/mermaidAPI.min.js - resources/icons/close_red.svg - resources/docs/shortcuts_en.md - resources/docs/shortcuts_zh.md - utils/showdown/showdown.min.js - resources/showdown.js - utils/showdown/showdown-headinganchor.js - resources/icons/print.svg - utils/markdown-it/markdown-it-sub.min.js - utils/markdown-it/markdown-it-sup.min.js - utils/markdown-it/markdown-it-footnote.min.js - resources/icons/vnote_update.svg - utils/flowchart.js/flowchart.min.js - utils/flowchart.js/raphael.min.js - resources/icons/bold.svg - resources/icons/italic.svg - resources/icons/strikethrough.svg - resources/icons/inline_code.svg - resources/icons/close_note_tb.svg - resources/icons/32x32/vnote.png - resources/icons/editing_modified.svg - resources/docs/markdown_guide_en.md - resources/docs/markdown_guide_zh.md - utils/highlightjs/highlightjs-line-numbers.min.js - resources/icons/recycle_bin.svg - resources/icons/empty_recycle_bin.svg - resources/icons/attachment.svg - resources/icons/add_attachment.svg - resources/icons/clear_attachment.svg - resources/icons/locate_attachment.svg - resources/icons/delete_attachment.svg - resources/icons/sort.svg - resources/icons/create_subdir.svg - resources/icons/compact_mode.svg - resources/icons/heading_sequence.svg - resources/icons/link.svg - resources/icons/code_block.svg - resources/icons/manage_template.svg - resources/icons/snippets.svg - resources/icons/add_snippet.svg - resources/icons/locate_snippet.svg - resources/icons/delete_snippet.svg - resources/icons/snippet_info.svg - resources/icons/apply_snippet.svg - resources/icons/reading_modified.svg - resources/icons/flash_page.svg - resources/icons/heading.svg - resources/themes/v_white/arrow_dropdown.svg - resources/themes/v_white/close.svg - resources/themes/v_white/close_grey.svg - resources/themes/v_white/float.svg - resources/themes/v_white/v_white.palette - resources/themes/v_white/v_white.qss - resources/themes/v_white/branch_closed.svg - resources/themes/v_white/branch_end.svg - resources/themes/v_white/branch_more.svg - resources/themes/v_white/branch_open.svg - resources/themes/v_white/line.svg - resources/themes/v_white/down.svg - resources/themes/v_white/left.svg - resources/themes/v_white/right.svg - resources/themes/v_white/up.svg - resources/themes/v_white/left_disabled.svg - resources/themes/v_white/right_disabled.svg - resources/themes/v_white/down_disabled.svg - resources/themes/v_white/up_disabled.svg - resources/themes/v_white/checkbox_checked.svg - resources/themes/v_white/checkbox_unchecked.svg - resources/themes/v_white/radiobutton_checked.svg - resources/themes/v_white/radiobutton_unchecked.svg - resources/themes/v_pure/arrow_dropdown.svg - resources/themes/v_pure/branch_closed.svg - resources/themes/v_pure/branch_end.svg - resources/themes/v_pure/branch_more.svg - resources/themes/v_pure/branch_open.svg - resources/themes/v_pure/checkbox_checked.svg - resources/themes/v_pure/checkbox_unchecked.svg - resources/themes/v_pure/close.svg - resources/themes/v_pure/close_grey.svg - resources/themes/v_pure/down.svg - resources/themes/v_pure/down_disabled.svg - resources/themes/v_pure/float.svg - resources/themes/v_pure/left.svg - resources/themes/v_pure/left_disabled.svg - resources/themes/v_pure/line.svg - resources/themes/v_pure/radiobutton_checked.svg - resources/themes/v_pure/radiobutton_unchecked.svg - resources/themes/v_pure/right.svg - resources/themes/v_pure/right_disabled.svg - resources/themes/v_pure/up.svg - resources/themes/v_pure/up_disabled.svg - resources/themes/v_pure/v_pure.palette - resources/themes/v_pure/v_pure.qss - resources/themes/v_white/menu_checkbox.svg - resources/themes/v_white/menu_radiobutton.svg - resources/themes/v_pure/menu_checkbox.svg - resources/themes/v_pure/menu_radiobutton.svg - resources/themes/v_pure/v_pure.mdhl - resources/themes/v_white/v_white.mdhl - resources/themes/v_white/v_white.css - resources/themes/v_pure/v_pure.css - resources/themes/v_pure/v_pure_codeblock.css - resources/themes/v_white/v_white_codeblock.css - resources/themes/v_material/arrow_dropdown.svg - resources/themes/v_material/branch_closed.svg - resources/themes/v_material/branch_end.svg - resources/themes/v_material/branch_more.svg - resources/themes/v_material/branch_open.svg - resources/themes/v_material/checkbox_checked.svg - resources/themes/v_material/checkbox_unchecked.svg - resources/themes/v_material/close.svg - resources/themes/v_material/close_grey.svg - resources/themes/v_material/down.svg - resources/themes/v_material/down_disabled.svg - resources/themes/v_material/float.svg - resources/themes/v_material/left.svg - resources/themes/v_material/left_disabled.svg - resources/themes/v_material/line.svg - resources/themes/v_material/menu_checkbox.svg - resources/themes/v_material/menu_radiobutton.svg - resources/themes/v_material/radiobutton_checked.svg - resources/themes/v_material/radiobutton_unchecked.svg - resources/themes/v_material/right.svg - resources/themes/v_material/right_disabled.svg - resources/themes/v_material/up.svg - resources/themes/v_material/up_disabled.svg - resources/themes/v_material/v_material.css - resources/themes/v_material/v_material.mdhl - resources/themes/v_material/v_material.palette - resources/themes/v_material/v_material.qss - resources/themes/v_material/v_material_codeblock.css - resources/themes/v_moonlight/arrow_dropdown.svg - resources/themes/v_moonlight/branch_closed.svg - resources/themes/v_moonlight/branch_open.svg - resources/themes/v_moonlight/checkbox_checked.svg - resources/themes/v_moonlight/checkbox_unchecked.svg - resources/themes/v_moonlight/close.svg - resources/themes/v_moonlight/close_grey.svg - resources/themes/v_moonlight/down.svg - resources/themes/v_moonlight/down_disabled.svg - resources/themes/v_moonlight/float.svg - resources/themes/v_moonlight/left.svg - resources/themes/v_moonlight/left_disabled.svg - resources/themes/v_moonlight/menu_checkbox.svg - resources/themes/v_moonlight/menu_radiobutton.svg - resources/themes/v_moonlight/radiobutton_checked.svg - resources/themes/v_moonlight/radiobutton_unchecked.svg - resources/themes/v_moonlight/right.svg - resources/themes/v_moonlight/right_disabled.svg - resources/themes/v_moonlight/up.svg - resources/themes/v_moonlight/up_disabled.svg - resources/themes/v_moonlight/v_moonlight.css - resources/themes/v_moonlight/v_moonlight.mdhl - resources/themes/v_moonlight/v_moonlight.palette - resources/themes/v_moonlight/v_moonlight.qss - resources/themes/v_moonlight/v_moonlight_codeblock.css - - diff --git a/src/vnotebook.cpp b/src/vnotebook.cpp deleted file mode 100644 index a4ecb3ae..00000000 --- a/src/vnotebook.cpp +++ /dev/null @@ -1,369 +0,0 @@ -#include "vnotebook.h" -#include -#include -#include "vdirectory.h" -#include "utils/vutils.h" -#include "vconfigmanager.h" -#include "vnotefile.h" - -extern VConfigManager *g_config; - -VNotebook::VNotebook(const QString &name, const QString &path, QObject *parent) - : QObject(parent), m_name(name), m_valid(false) -{ - m_path = QDir::cleanPath(path); - m_recycleBinFolder = g_config->getRecycleBinFolder(); - m_rootDir = new VDirectory(this, - NULL, - VUtils::directoryNameFromPath(path), - QDateTime::currentDateTimeUtc()); -} - -VNotebook::~VNotebook() -{ - delete m_rootDir; -} - -bool VNotebook::readConfigNotebook() -{ - QJsonObject configJson = VConfigManager::readDirectoryConfig(m_path); - if (configJson.isEmpty()) { - qWarning() << "fail to read notebook configuration" << m_path; - m_valid = false; - return false; - } - - // [image_folder] section. - auto it = configJson.find(DirConfig::c_imageFolder); - if (it != configJson.end()) { - m_imageFolder = it.value().toString(); - } - - // [recycle_bin_folder] section. - it = configJson.find(DirConfig::c_recycleBinFolder); - if (it != configJson.end()) { - m_recycleBinFolder = it.value().toString(); - } - - // [attachment_folder] section. - // SHOULD be processed at last. - it = configJson.find(DirConfig::c_attachmentFolder); - if (it != configJson.end()) { - m_attachmentFolder = it.value().toString(); - } - - // We do not allow empty attachment folder. - if (m_attachmentFolder.isEmpty()) { - m_attachmentFolder = g_config->getAttachmentFolder(); - Q_ASSERT(!m_attachmentFolder.isEmpty()); - writeConfigNotebook(); - } - - m_valid = true; - return true; -} - -QJsonObject VNotebook::toConfigJsonNotebook() const -{ - QJsonObject json; - - // [image_folder] section. - json[DirConfig::c_imageFolder] = m_imageFolder; - - // [attachment_folder] section. - json[DirConfig::c_attachmentFolder] = m_attachmentFolder; - - // [recycle_bin_folder] section. - json[DirConfig::c_recycleBinFolder] = m_recycleBinFolder; - - return json; -} - -QJsonObject VNotebook::toConfigJson() const -{ - QJsonObject json = m_rootDir->toConfigJson(); - QJsonObject nbJson = toConfigJsonNotebook(); - - // Merge nbJson to json. - for (auto it = nbJson.begin(); it != nbJson.end(); ++it) { - V_ASSERT(!json.contains(it.key())); - json[it.key()] = it.value(); - } - - return json; -} - -bool VNotebook::writeToConfig() const -{ - return VConfigManager::writeDirectoryConfig(m_path, toConfigJson()); -} - -bool VNotebook::writeConfigNotebook() const -{ - QJsonObject nbJson = toConfigJsonNotebook(); - - QJsonObject configJson = VConfigManager::readDirectoryConfig(m_path); - if (configJson.isEmpty()) { - qWarning() << "fail to read notebook configuration" << m_path; - return false; - } - - for (auto it = nbJson.begin(); it != nbJson.end(); ++it) { - configJson[it.key()] = it.value(); - } - - return VConfigManager::writeDirectoryConfig(m_path, configJson); -} - -const QString &VNotebook::getName() const -{ - return m_name; -} - -const QString &VNotebook::getPath() const -{ - return m_path; -} - -void VNotebook::close() -{ - m_rootDir->close(); -} - -bool VNotebook::open() -{ - QString recycleBinPath = getRecycleBinFolderPath(); - if (!QFileInfo::exists(recycleBinPath)) { - QDir dir(m_path); - if (!dir.mkpath(recycleBinPath)) { - qWarning() << "fail to create recycle bin folder" << recycleBinPath - << "for notebook" << m_name; - return false; - } - } - - return m_rootDir->open(); -} - -VNotebook *VNotebook::createNotebook(const QString &p_name, - const QString &p_path, - bool p_import, - const QString &p_imageFolder, - const QString &p_attachmentFolder, - QObject *p_parent) -{ - VNotebook *nb = new VNotebook(p_name, p_path, p_parent); - - // If @p_imageFolder is empty, it will report global configured folder as - // its image folder. - nb->setImageFolder(p_imageFolder); - - // If @p_attachmentFolder is empty, use global configured folder. - QString attachmentFolder = p_attachmentFolder; - if (attachmentFolder.isEmpty()) { - attachmentFolder = g_config->getAttachmentFolder(); - } - - nb->setAttachmentFolder(attachmentFolder); - - // Check if there alread exists a config file. - if (p_import && VConfigManager::directoryConfigExist(p_path)) { - qDebug() << "import existing notebook"; - nb->readConfigNotebook(); - return nb; - } - - VUtils::makePath(p_path); - - if (!nb->writeToConfig()) { - delete nb; - return NULL; - } - - return nb; -} - -bool VNotebook::deleteNotebook(VNotebook *p_notebook, bool p_deleteFiles) -{ - bool ret = true; - - if (!p_notebook) { - return true; - } - - if (p_deleteFiles) { - if (!p_notebook->open()) { - qWarning() << "fail to open notebook" << p_notebook->getName() - << "to delete"; - ret = false; - goto exit; - } - - // Delete sub directories. - VDirectory *rootDir = p_notebook->getRootDir(); - QVector subdirs = rootDir->getSubDirs(); - for (auto dir : subdirs) { - // Skip recycle bin. - VDirectory::deleteDirectory(dir, true); - } - - // Delete the recycle bin. - QDir recycleDir(p_notebook->getRecycleBinFolderPath()); - if (!recycleDir.removeRecursively()) { - qWarning() << "fail to delete notebook recycle bin folder" - << p_notebook->getRecycleBinFolderPath(); - ret = false; - } - - // Delete the config file. - if (!VConfigManager::deleteDirectoryConfig(p_notebook->getPath())) { - ret = false; - goto exit; - } - - // If it is now an empty directory, delete it. - QDir dir(p_notebook->getPath()); - dir.cdUp(); - if (!dir.rmdir(rootDir->getName())) { - qWarning() << "fail to delete notebook root folder" << rootDir->getName(); - ret = false; - } - } - -exit: - p_notebook->close(); - delete p_notebook; - - return ret; -} - -void VNotebook::rename(const QString &p_name) -{ - if (p_name == m_name || p_name.isEmpty()) { - return; - } - - m_name = p_name; -} - -bool VNotebook::containsFile(const VFile *p_file) const -{ - return m_rootDir->containsFile(p_file); -} - -VNoteFile *VNotebook::tryLoadFile(const QString &p_path) -{ - QFileInfo fi(p_path); - Q_ASSERT(fi.isAbsolute()); - if (!fi.exists()) { - return NULL; - } - - QStringList filePath; - if (VUtils::splitPathInBasePath(m_path, p_path, filePath)) { - if (filePath.isEmpty()) { - return NULL; - } - - bool opened = isOpened(); - if (!open()) { - return NULL; - } - - VNoteFile *file = m_rootDir->tryLoadFile(filePath); - - if (!file && !opened) { - close(); - } - - return file; - } - - return NULL; -} - -VDirectory *VNotebook::tryLoadDirectory(const QString &p_path) -{ - QFileInfo fi(p_path); - Q_ASSERT(fi.isAbsolute()); - if (!fi.exists()) { - return NULL; - } - - QStringList filePath; - if (VUtils::splitPathInBasePath(m_path, p_path, filePath)) { - if (filePath.isEmpty()) { - return NULL; - } - - bool opened = isOpened(); - if (!open()) { - return NULL; - } - - VDirectory *dir = m_rootDir->tryLoadDirectory(filePath); - - if (!dir && !opened) { - close(); - } - - return dir; - } - - return NULL; -} - -const QString &VNotebook::getImageFolder() const -{ - if (m_imageFolder.isEmpty()) { - return g_config->getImageFolder(); - } else { - return m_imageFolder; - } -} - -void VNotebook::setImageFolder(const QString &p_imageFolder) -{ - m_imageFolder = p_imageFolder; -} - -const QString &VNotebook::getImageFolderConfig() const -{ - return m_imageFolder; -} - -const QString &VNotebook::getAttachmentFolder() const -{ - return m_attachmentFolder; -} - -void VNotebook::setAttachmentFolder(const QString &p_attachmentFolder) -{ - m_attachmentFolder = p_attachmentFolder; -} - -bool VNotebook::isOpened() const -{ - return m_rootDir->isOpened(); -} - -QDateTime VNotebook::getCreatedTimeUtc() -{ - if (!isOpened()) { - if (!open()) { - return QDateTime(); - } - } - - return m_rootDir->getCreatedTimeUtc(); -} - -QString VNotebook::getRecycleBinFolderPath() const -{ - QFileInfo fi(m_recycleBinFolder); - if (fi.isAbsolute()) { - return m_recycleBinFolder; - } else { - return QDir(m_path).filePath(m_recycleBinFolder); - } -} diff --git a/src/vnotebook.h b/src/vnotebook.h deleted file mode 100644 index 316ca109..00000000 --- a/src/vnotebook.h +++ /dev/null @@ -1,144 +0,0 @@ -#ifndef VNOTEBOOK_H -#define VNOTEBOOK_H - -#include -#include -#include - -class VDirectory; -class VFile; -class VNoteFile; - -class VNotebook : public QObject -{ - Q_OBJECT -public: - VNotebook(const QString &name, const QString &path, QObject *parent = 0); - - ~VNotebook(); - - // Open the root directory to load contents - bool open(); - - // Whether this notebook is opened. - bool isOpened() const; - - // Close all the directory and files of this notebook. - // Please make sure all files belonging to this notebook have been closed in the tab. - void close(); - - bool containsFile(const VFile *p_file) const; - - // Try to load the file @p_path. - // Returns the corresponding VNoteFile struct if @p_path is a note inside this notebook. - // Otherwise, returns NULL. - // If notebook is not opened currently, it will open itself and close itself - // if @p_path is not inside this notebook. - VNoteFile *tryLoadFile(const QString &p_path); - - // Try to load the directory @p_path. - // Returns the corresponding VDirectory struct if @p_path is a folder inside this notebook. - // Otherwise, returns NULL. - // If notebook is not opened currently, it will open itself and close itself - // if @p_path is not inside this notebook. - VDirectory *tryLoadDirectory(const QString &p_path); - - const QString &getName() const; - const QString &getPath() const; - - VDirectory *getRootDir() const; - - void rename(const QString &p_name); - - static VNotebook *createNotebook(const QString &p_name, - const QString &p_path, - bool p_import, - const QString &p_imageFolder, - const QString &p_attachmentFolder, - QObject *p_parent = 0); - - static bool deleteNotebook(VNotebook *p_notebook, bool p_deleteFiles); - - // Get the image folder for this notebook to use (not exactly the same as - // m_imageFolder if it is empty). - const QString &getImageFolder() const; - - // Return m_imageFolder. - const QString &getImageFolderConfig() const; - - // Different from image folder. We could not change the attachment folder - // of a notebook once it has been created. - // Get the attachment folder for this notebook to use. - const QString &getAttachmentFolder() const; - - // Return m_recycleBinFolder. - const QString &getRecycleBinFolder() const; - - // Get the recycle folder path for this notebook to use. - QString getRecycleBinFolderPath() const; - - void setImageFolder(const QString &p_imageFolder); - - void setAttachmentFolder(const QString &p_attachmentFolder); - - // Read configurations (only notebook part) directly from root directory config file. - bool readConfigNotebook(); - - // Write configurations only related to notebook to root directory config file. - bool writeConfigNotebook() const; - - // Return only the info of notebook part in json. - QJsonObject toConfigJsonNotebook() const; - - // Need to check if this notebook has been opened. - QDateTime getCreatedTimeUtc(); - - bool isValid() const; - -private: - // Serialize current instance to json. - QJsonObject toConfigJson() const; - - // Write current instance to config file. - bool writeToConfig() const; - - QString m_name; - QString m_path; - - // Folder name to store images. - // If not empty, VNote will store images in this folder within the same directory of the note. - // Otherwise, VNote will use the global configured folder. - QString m_imageFolder; - - // Folder name to store attachments. - // Should not be empty and changed once a notebook is created. - QString m_attachmentFolder; - - // Folder name to store deleted files. - // Could be relative or absolute. - QString m_recycleBinFolder; - - // Parent is NULL for root directory - VDirectory *m_rootDir; - - // Whether this notebook is valid. - // Will set to true after readConfigNotebook(). - bool m_valid; -}; - -inline VDirectory *VNotebook::getRootDir() const -{ - return m_rootDir; -} - -inline const QString &VNotebook::getRecycleBinFolder() const -{ - return m_recycleBinFolder; -} - -inline bool VNotebook::isValid() const -{ - return m_valid; -} - -#endif // VNOTEBOOK_H diff --git a/src/vnotebookselector.cpp b/src/vnotebookselector.cpp deleted file mode 100644 index d56275dc..00000000 --- a/src/vnotebookselector.cpp +++ /dev/null @@ -1,621 +0,0 @@ -#include "vnotebookselector.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "vnotebook.h" -#include "vconfigmanager.h" -#include "dialog/vnewnotebookdialog.h" -#include "dialog/vnotebookinfodialog.h" -#include "dialog/vdeletenotebookdialog.h" -#include "vnotebook.h" -#include "vdirectory.h" -#include "utils/vutils.h" -#include "vnote.h" -#include "veditarea.h" -#include "vnofocusitemdelegate.h" -#include "vmainwindow.h" -#include "utils/vimnavigationforwidget.h" -#include "utils/viconutils.h" - -extern VConfigManager *g_config; - -extern VNote *g_vnote; - -extern VMainWindow *g_mainWin; - -VNotebookSelector::VNotebookSelector(QWidget *p_parent) - : QComboBox(p_parent), - VNavigationMode(), - m_notebooks(g_vnote->getNotebooks()), - m_lastValidIndex(-1), - m_muted(false), - m_naviLabel(NULL) -{ - m_listWidget = new QListWidget(this); - m_listWidget->setItemDelegate(new VNoFocusItemDelegate(this)); - m_listWidget->setContextMenuPolicy(Qt::CustomContextMenu); - connect(m_listWidget, &QListWidget::customContextMenuRequested, - this, &VNotebookSelector::popupListContextMenuRequested); - - setModel(m_listWidget->model()); - setView(m_listWidget); - - m_listWidget->viewport()->installEventFilter(this); - m_listWidget->installEventFilter(this); - - initActions(); - - connect(this, SIGNAL(currentIndexChanged(int)), - this, SLOT(handleCurIndexChanged(int))); -} - -void VNotebookSelector::initActions() -{ - m_deleteNotebookAct = new QAction(VIconUtils::menuDangerIcon(":/resources/icons/delete_notebook.svg"), - tr("&Delete"), this); - m_deleteNotebookAct->setToolTip(tr("Delete current notebook")); - connect(m_deleteNotebookAct, SIGNAL(triggered(bool)), - this, SLOT(deleteNotebook())); - - m_notebookInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/notebook_info.svg"), - tr("&Info"), this); - m_notebookInfoAct->setToolTip(tr("View and edit current notebook's information")); - connect(m_notebookInfoAct, SIGNAL(triggered(bool)), - this, SLOT(editNotebookInfo())); - - m_openLocationAct = new QAction(tr("&Open Notebook Location"), this); - m_openLocationAct->setToolTip(tr("Open the root folder of this notebook in operating system")); - connect(m_openLocationAct, &QAction::triggered, - this, [this]() { - QList items = this->m_listWidget->selectedItems(); - if (items.isEmpty()) { - return; - } - - Q_ASSERT(items.size() == 1); - VNotebook *notebook = getNotebook(items[0]); - QUrl url = QUrl::fromLocalFile(notebook->getPath()); - QDesktopServices::openUrl(url); - }); - - m_recycleBinAct = new QAction(VIconUtils::menuIcon(":/resources/icons/recycle_bin.svg"), - tr("&Recycle Bin"), this); - m_recycleBinAct->setToolTip(tr("Open the recycle bin of this notebook")); - connect(m_recycleBinAct, &QAction::triggered, - this, [this]() { - QList items = this->m_listWidget->selectedItems(); - if (items.isEmpty()) { - return; - } - - Q_ASSERT(items.size() == 1); - VNotebook *notebook = getNotebook(items[0]); - QUrl url = QUrl::fromLocalFile(notebook->getRecycleBinFolderPath()); - QDesktopServices::openUrl(url); - }); - - m_emptyRecycleBinAct = new QAction(VIconUtils::menuDangerIcon(":/resources/icons/empty_recycle_bin.svg"), - tr("&Empty Recycle Bin"), this); - m_emptyRecycleBinAct->setToolTip(tr("Empty the recycle bin of this notebook")); - connect(m_emptyRecycleBinAct, &QAction::triggered, - this, [this]() { - QList items = this->m_listWidget->selectedItems(); - if (items.isEmpty()) { - return; - } - - Q_ASSERT(items.size() == 1); - VNotebook *notebook = getNotebook(items[0]); - QString binPath = notebook->getRecycleBinFolderPath(); - - int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Are you sure to empty recycle bin of notebook " - "%2?") - .arg(g_config->c_dataTextStyle) - .arg(notebook->getName()), - tr("WARNING: " - "VNote will delete all the files in directory " - "%3." - "
    It may be UNRECOVERABLE!") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(binPath), - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Ok, - this, - MessageBoxType::Danger); - if (ret == QMessageBox::Ok) { - QString info; - if (VUtils::emptyDirectory(notebook, binPath, true)) { - info = tr("Successfully emptied recycle bin of notebook " - "%2!") - .arg(g_config->c_dataTextStyle) - .arg(notebook->getName()); - } else { - info = tr("Fail to empty recycle bin of notebook " - "%2!") - .arg(g_config->c_dataTextStyle) - .arg(notebook->getName()); - } - - VUtils::showMessage(QMessageBox::Information, - tr("Information"), - info, - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - }); -} - -void VNotebookSelector::updateComboBox() -{ - m_muted = true; - - int index = g_config->getCurNotebookIndex(); - - clear(); - - m_listWidget->clear(); - - insertAddNotebookItem(); - - for (int i = 0; i < m_notebooks.size(); ++i) { - addNotebookItem(m_notebooks[i]); - } - - setCurrentIndex(-1); - - m_muted = false; - - if (m_notebooks.isEmpty()) { - g_config->setCurNotebookIndex(-1); - setCurrentIndex(0); - } else { - const VNotebook *nb = NULL; - if (index >= 0 && index < m_notebooks.size()) { - nb = m_notebooks[index]; - } - - setCurrentItemToNotebook(nb); - } - - qDebug() << "notebooks" << m_notebooks.size() << "current index" << index; -} - -void VNotebookSelector::setCurrentItemToNotebook(const VNotebook *p_notebook) -{ - setCurrentIndex(itemIndexOfNotebook(p_notebook)); -} - -int VNotebookSelector::itemIndexOfNotebook(const VNotebook *p_notebook) const -{ - if (!p_notebook) { - return -1; - } - - qulonglong ptr = (qulonglong)p_notebook; - int cnt = m_listWidget->count(); - for (int i = 0; i < cnt; ++i) { - QListWidgetItem *item = m_listWidget->item(i); - if (item->data(Qt::UserRole).toULongLong() == ptr) { - return i; - } - } - - return -1; -} - -void VNotebookSelector::insertAddNotebookItem() -{ - QListWidgetItem *item = new QListWidgetItem(); - item->setIcon(VIconUtils::comboBoxIcon(":/resources/icons/create_notebook.svg")); - item->setText(tr("Add Notebook")); - QFont font; - font.setItalic(true); - item->setData(Qt::FontRole, font); - item->setToolTip(tr("Create or import a notebook")); - - m_listWidget->insertItem(0, item); -} - -void VNotebookSelector::handleCurIndexChanged(int p_index) -{ - if (m_muted) { - return; - } - - QString tooltip = tr("View and edit notebooks"); - VNotebook *nb = NULL; - if (p_index > -1) { - nb = getNotebook(p_index); - if (!nb) { - // Add notebook. - setToolTip(tooltip); - - if (m_lastValidIndex != p_index && m_lastValidIndex > -1) { - setCurrentIndex(m_lastValidIndex); - } - - if (!m_notebooks.isEmpty()) { - newNotebook(); - } - - return; - } - } - - m_lastValidIndex = p_index; - - int nbIdx = -1; - if (nb) { - tooltip = nb->getName(); - - nbIdx = m_notebooks.indexOf(nb); - Q_ASSERT(nbIdx > -1); - } - - g_config->setCurNotebookIndex(nbIdx); - - setToolTip(tooltip); - - emit curNotebookChanged(nb); -} - -void VNotebookSelector::update() -{ - updateComboBox(); -} - -bool VNotebookSelector::newNotebook() -{ - QString info(tr("Please type the name of the notebook and " - "choose a folder as the Root Folder of the notebook.")); - info += "\n"; - info += tr("* The root folder should be used EXCLUSIVELY by VNote and " - "it is recommended to be EMPTY."); - info += "\n"; - info += tr("* A previously created notebook could be imported into VNote " - "by choosing its root folder."); - - // Use empty default name and path to let the dialog to auto generate a name - // under the default VNote notebook folder. - VNewNotebookDialog dialog(tr("Add Notebook"), - info, - "", - "", - m_notebooks, - this); - if (dialog.exec() == QDialog::Accepted) { - createNotebook(dialog.getNameInput(), - dialog.getPathInput(), - dialog.isImportExistingNotebook(), - dialog.getImageFolder(), - dialog.getAttachmentFolder()); - - emit notebookCreated(dialog.getNameInput(), dialog.isImportExistingNotebook()); - return true; - } - - return false; -} - -void VNotebookSelector::createNotebook(const QString &p_name, - const QString &p_path, - bool p_import, - const QString &p_imageFolder, - const QString &p_attachmentFolder) -{ - VNotebook *nb = VNotebook::createNotebook(p_name, p_path, p_import, - p_imageFolder, p_attachmentFolder, - g_vnote); - if (!nb) { - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Fail to create notebook " - "%2 in %3.") - .arg(g_config->c_dataTextStyle).arg(p_name).arg(p_path), "", - QMessageBox::Ok, QMessageBox::Ok, this); - return; - } - - m_notebooks.append(nb); - g_config->setNotebooks(m_notebooks); - - addNotebookItem(nb); - setCurrentItemToNotebook(nb); -} - -void VNotebookSelector::deleteNotebook() -{ - QList items = m_listWidget->selectedItems(); - if (items.isEmpty()) { - return; - } - - Q_ASSERT(items.size() == 1); - - VNotebook *notebook = getNotebook(items[0]); - Q_ASSERT(notebook); - - VDeleteNotebookDialog dialog(tr("Delete Notebook"), notebook, this); - if (dialog.exec() == QDialog::Accepted) { - bool deleteFiles = dialog.getDeleteFiles(); - g_mainWin->getEditArea()->closeFile(notebook, true); - deleteNotebook(notebook, deleteFiles); - } -} - -void VNotebookSelector::deleteNotebook(VNotebook *p_notebook, bool p_deleteFiles) -{ - Q_ASSERT(p_notebook); - - m_notebooks.removeOne(p_notebook); - g_config->setNotebooks(m_notebooks); - - int idx = itemIndexOfNotebook(p_notebook); - QListWidgetItem *item = m_listWidget->takeItem(idx); - Q_ASSERT(item); - delete item; - - QString name(p_notebook->getName()); - QString path(p_notebook->getPath()); - bool ret = VNotebook::deleteNotebook(p_notebook, p_deleteFiles); - if (!ret) { - // Notebook could not be deleted completely. - int cho = VUtils::showMessage(QMessageBox::Information, - tr("Delete Notebook Folder From Disk"), - tr("Fail to delete the root folder of notebook " - "%2 from disk. You may open " - "the folder and check it manually.") - .arg(g_config->c_dataTextStyle).arg(name), - "", - QMessageBox::Open | QMessageBox::Ok, - QMessageBox::Ok, - this); - if (cho == QMessageBox::Open) { - // Open the notebook location. - QUrl url = QUrl::fromLocalFile(path); - QDesktopServices::openUrl(url); - } - } - - if (m_notebooks.isEmpty()) { - m_muted = true; - setCurrentIndex(0); - m_muted = false; - } -} - -void VNotebookSelector::editNotebookInfo() -{ - QList items = m_listWidget->selectedItems(); - if (items.isEmpty()) { - return; - } - - Q_ASSERT(items.size() == 1); - - VNotebook *notebook = getNotebook(items[0]); - VNotebookInfoDialog dialog(tr("Notebook Information"), - "", - notebook, - m_notebooks, - this); - if (dialog.exec() == QDialog::Accepted) { - bool updated = false; - bool configUpdated = false; - QString name = dialog.getName(); - if (name != notebook->getName()) { - updated = true; - notebook->rename(name); - g_config->setNotebooks(m_notebooks); - } - - QString imageFolder = dialog.getImageFolder(); - if (imageFolder != notebook->getImageFolderConfig()) { - configUpdated = true; - notebook->setImageFolder(imageFolder); - } - - if (configUpdated) { - updated = true; - notebook->writeConfigNotebook(); - } - - if (updated) { - fillItem(items[0], notebook); - emit notebookUpdated(notebook); - } - } -} - -void VNotebookSelector::addNotebookItem(const VNotebook *p_notebook) -{ - QListWidgetItem *item = new QListWidgetItem(m_listWidget); - fillItem(item, p_notebook); -} - -void VNotebookSelector::fillItem(QListWidgetItem *p_item, - const VNotebook *p_notebook) const -{ - p_item->setText(p_notebook->getName()); - p_item->setToolTip(p_notebook->getName()); - p_item->setIcon(VIconUtils::comboBoxIcon(":/resources/icons/notebook_item.svg")); - p_item->setData(Qt::UserRole, (qulonglong)p_notebook); -} - - -void VNotebookSelector::popupListContextMenuRequested(QPoint p_pos) -{ - QListWidgetItem *item = m_listWidget->itemAt(p_pos); - if (!item) { - return; - } - - const VNotebook *nb = getNotebook(item); - if (!nb) { - return; - } - - m_listWidget->clearSelection(); - item->setSelected(true); - - QMenu menu(this); - menu.setToolTipsVisible(true); - menu.addAction(m_deleteNotebookAct); - if (nb->isValid()) { - menu.addSeparator(); - menu.addAction(m_recycleBinAct); - menu.addAction(m_emptyRecycleBinAct); - } - - menu.addSeparator(); - menu.addAction(m_openLocationAct); - - if (nb->isValid()) { - menu.addAction(m_notebookInfoAct); - } - - menu.exec(m_listWidget->mapToGlobal(p_pos)); -} - -bool VNotebookSelector::eventFilter(QObject *watched, QEvent *event) -{ - QEvent::Type type = event->type(); - if (type == QEvent::KeyPress && watched == m_listWidget) { - if (handlePopupKeyPress(static_cast(event))) { - return true; - } - } else if (type == QEvent::MouseButtonRelease) { - if (static_cast(event)->button() == Qt::RightButton) { - return true; - } - } - - return QComboBox::eventFilter(watched, event); -} - -bool VNotebookSelector::locateNotebook(const VNotebook *p_notebook) -{ - bool ret = false; - int index = itemIndexOfNotebook(p_notebook); - if (index > -1) { - setCurrentIndex(index); - ret = true; - } - - return ret; -} - -void VNotebookSelector::showPopup() -{ - if (m_notebooks.isEmpty()) { - // No normal notebook items. Just add notebook. - newNotebook(); - return; - } - - resizeListWidgetToContent(); - QComboBox::showPopup(); -} - -void VNotebookSelector::resizeListWidgetToContent() -{ - static QRect screenRect = QGuiApplication::primaryScreen()->geometry(); - static int maxMinWidth = screenRect.width() < 400 ? screenRect.width() : screenRect.width() / 2; - static int maxMinHeight = screenRect.height() < 400 ? screenRect.height() : screenRect.height() / 2; - - int minWidth = 0; - int minHeight = 0; - if (m_listWidget->count() > 0) { - // Width - minWidth = m_listWidget->sizeHintForColumn(0); - minWidth = qMin(minWidth, maxMinWidth); - - // Height - minHeight = m_listWidget->sizeHintForRow(0) * m_listWidget->count() + 10; - minHeight = qMin(minHeight, maxMinHeight); - } - - m_listWidget->setMinimumSize(minWidth, minHeight); -} - -void VNotebookSelector::registerNavigation(QChar p_majorKey) -{ - Q_ASSERT(!m_naviLabel); - m_majorKey = p_majorKey; -} - -void VNotebookSelector::showNavigation() -{ - if (!isVisible()) { - return; - } - - V_ASSERT(!m_naviLabel); - m_naviLabel = new QLabel(m_majorKey, this); - m_naviLabel->setStyleSheet(g_vnote->getNavigationLabelStyle(m_majorKey)); - m_naviLabel->show(); -} - -void VNotebookSelector::hideNavigation() -{ - if (m_naviLabel) { - delete m_naviLabel; - m_naviLabel = NULL; - } -} - -bool VNotebookSelector::handleKeyNavigation(int p_key, bool &p_succeed) -{ - bool ret = false; - p_succeed = false; - QChar keyChar = VUtils::keyToChar(p_key); - if (keyChar == m_majorKey) { - // Hit. - p_succeed = true; - ret = true; - if (m_naviLabel) { - showPopup(); - } - } - return ret; -} - -bool VNotebookSelector::handlePopupKeyPress(QKeyEvent *p_event) -{ - if (VimNavigationForWidget::injectKeyPressEventForVim(m_listWidget, - p_event)) { - return true; - } - - return false; -} - -VNotebook *VNotebookSelector::getNotebook(int p_itemIdx) const -{ - VNotebook *nb = NULL; - QListWidgetItem *item = m_listWidget->item(p_itemIdx); - if (item) { - nb = (VNotebook *)item->data(Qt::UserRole).toULongLong(); - } - - return nb; -} - -VNotebook *VNotebookSelector::getNotebook(const QListWidgetItem *p_item) const -{ - if (p_item) { - return (VNotebook *)p_item->data(Qt::UserRole).toULongLong(); - } - - return NULL; -} diff --git a/src/vnotebookselector.h b/src/vnotebookselector.h deleted file mode 100644 index cfb875d4..00000000 --- a/src/vnotebookselector.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef VNOTEBOOKSELECTOR_H -#define VNOTEBOOKSELECTOR_H - -#include -#include -#include -#include "vnavigationmode.h" - -class VNotebook; -class QListWidget; -class QAction; -class QListWidgetItem; -class QLabel; - -class VNotebookSelector : public QComboBox, public VNavigationMode -{ - Q_OBJECT -public: - explicit VNotebookSelector(QWidget *p_parent = 0); - - // Update Combox from m_notebooks. - void update(); - - // Select notebook @p_notebook. - bool locateNotebook(const VNotebook *p_notebook); - - // Add notebook on popup if no notebooks currently. - void showPopup() Q_DECL_OVERRIDE; - - // Implementations for VNavigationMode. - void registerNavigation(QChar p_majorKey) Q_DECL_OVERRIDE; - void showNavigation() Q_DECL_OVERRIDE; - void hideNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - -signals: - void curNotebookChanged(VNotebook *p_notebook); - - // Info of current notebook was changed. - void notebookUpdated(const VNotebook *p_notebook); - - // Emit after creating a new notebook. - void notebookCreated(const QString &p_name, bool p_import); - -public slots: - // Popup a dialog to prompt user to create a notebook. - bool newNotebook(); - -protected: - bool eventFilter(QObject *watched, QEvent *event) Q_DECL_OVERRIDE; - -private slots: - // Act to currentIndexChanged() signal if m_muted is false. - void handleCurIndexChanged(int p_index); - - void popupListContextMenuRequested(QPoint p_pos); - - // Delete currently selected notebook. - void deleteNotebook(); - - // View and edit notebook information of selected notebook. - void editNotebookInfo(); - -private: - void initActions(); - - // Update Combox from m_notebooks. - void updateComboBox(); - - // Return the item index of @p_notebook. - int itemIndexOfNotebook(const VNotebook *p_notebook) const; - - // If @p_import is true, we will use the existing config file. - // If @p_imageFolder is empty, we will use the global one. - // If @p_attachmentFolder is empty, we will use the global one. - void createNotebook(const QString &p_name, const QString &p_path, - bool p_import, const QString &p_imageFolder, - const QString &p_attachmentFolder); - - void deleteNotebook(VNotebook *p_notebook, bool p_deleteFiles); - - // Add an item corresponding to @p_notebook to combo box. - void addNotebookItem(const VNotebook *p_notebook); - - void fillItem(QListWidgetItem *p_item, const VNotebook *p_notebook) const; - - // Insert "Add Notebook" item to combo box. - void insertAddNotebookItem(); - - // Set current item corresponding to @p_notebook. - void setCurrentItemToNotebook(const VNotebook *p_notebook); - - // Get VNotebook from @p_itemIdx, the index of m_listWidget. - VNotebook *getNotebook(int p_itemIdx) const; - - VNotebook *getNotebook(const QListWidgetItem *p_item) const; - - void resizeListWidgetToContent(); - - bool handlePopupKeyPress(QKeyEvent *p_event); - - QVector &m_notebooks; - - QListWidget *m_listWidget; - - // Used to restore after clicking Add Notebook item. - int m_lastValidIndex; - - // Whether it is muted from currentIndexChanged(). - bool m_muted; - - // Actions - QAction *m_deleteNotebookAct; - QAction *m_notebookInfoAct; - QAction *m_openLocationAct; - QAction *m_recycleBinAct; - QAction *m_emptyRecycleBinAct; - - QLabel *m_naviLabel; -}; - -#endif // VNOTEBOOKSELECTOR_H diff --git a/src/vnotefile.cpp b/src/vnotefile.cpp deleted file mode 100644 index 09f96a02..00000000 --- a/src/vnotefile.cpp +++ /dev/null @@ -1,589 +0,0 @@ -#include "vnotefile.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "utils/vutils.h" -#include "vdirectory.h" - -VNoteFile::VNoteFile(VDirectory *p_directory, - const QString &p_name, - FileType p_type, - bool p_modifiable, - QDateTime p_createdTimeUtc, - QDateTime p_modifiedTimeUtc, - const QString &p_attachmentFolder, - const QVector &p_attachments) - : VFile(p_directory, p_name, p_type, p_modifiable, p_createdTimeUtc, p_modifiedTimeUtc), - m_attachmentFolder(p_attachmentFolder), - m_attachments(p_attachments) -{ -} - -QString VNoteFile::fetchPath() const -{ - return QDir(getDirectory()->fetchPath()).filePath(m_name); -} - -QString VNoteFile::fetchBasePath() const -{ - return getDirectory()->fetchPath(); -} - -QString VNoteFile::fetchImageFolderPath() const -{ - return QDir(fetchBasePath()).filePath(getNotebook()->getImageFolder()); -} - -bool VNoteFile::useRelativeImageFolder() const -{ - // Always use relative image folder. - return true; -} - -QString VNoteFile::getImageFolderInLink() const -{ - return getNotebook()->getImageFolder(); -} - -void VNoteFile::setName(const QString &p_name) -{ - m_name = p_name; -} - -bool VNoteFile::rename(const QString &p_name) -{ - if (m_name == p_name) { - return true; - } - - QString oldName = m_name; - - VDirectory *dir = getDirectory(); - Q_ASSERT(dir); - - // Rename it in disk. - QDir diskDir(dir->fetchPath()); - if (!diskDir.rename(m_name, p_name)) { - qWarning() << "fail to rename file" << m_name << "to" << p_name << "in disk"; - return false; - } - - m_name = p_name; - - // Update parent directory's config file. - if (!dir->updateFileConfig(this)) { - m_name = oldName; - diskDir.rename(p_name, m_name); - return false; - } - - // Can't not change doc type. - Q_ASSERT(m_docType == DocType::Unknown - || m_docType == VUtils::docTypeFromName(m_name)); - - m_docType = VUtils::docTypeFromName(m_name); - - qDebug() << "file renamed from" << oldName << "to" << m_name; - return true; -} - -VDirectory *VNoteFile::getDirectory() -{ - Q_ASSERT(parent()); - return (VDirectory *)parent(); -} - -const VDirectory *VNoteFile::getDirectory() const -{ - Q_ASSERT(parent()); - return (const VDirectory *)parent(); -} - -VNotebook *VNoteFile::getNotebook() -{ - return getDirectory()->getNotebook(); -} - -const VNotebook *VNoteFile::getNotebook() const -{ - return getDirectory()->getNotebook(); -} - -QString VNoteFile::getNotebookName() const -{ - return getDirectory()->getNotebookName(); -} - -QString VNoteFile::fetchRelativePath() const -{ - return QDir(getDirectory()->fetchRelativePath()).filePath(m_name); -} - -VNoteFile *VNoteFile::fromJson(VDirectory *p_directory, - const QJsonObject &p_json, - FileType p_type, - bool p_modifiable) -{ - // Attachments. - QJsonArray attachmentJson = p_json[DirConfig::c_attachments].toArray(); - QVector attachments; - for (int i = 0; i < attachmentJson.size(); ++i) { - QJsonObject attachmentItem = attachmentJson[i].toObject(); - attachments.push_back(VAttachment(attachmentItem[DirConfig::c_name].toString())); - } - - return new VNoteFile(p_directory, - p_json[DirConfig::c_name].toString(), - p_type, - p_modifiable, - QDateTime::fromString(p_json[DirConfig::c_createdTime].toString(), - Qt::ISODate), - QDateTime::fromString(p_json[DirConfig::c_modifiedTime].toString(), - Qt::ISODate), - p_json[DirConfig::c_attachmentFolder].toString(), - attachments); -} - -QJsonObject VNoteFile::toConfigJson() const -{ - QJsonObject item; - item[DirConfig::c_name] = m_name; - item[DirConfig::c_createdTime] = m_createdTimeUtc.toString(Qt::ISODate); - item[DirConfig::c_modifiedTime] = m_modifiedTimeUtc.toString(Qt::ISODate); - item[DirConfig::c_attachmentFolder] = m_attachmentFolder; - - // Attachments. - QJsonArray attachmentJson; - for (int i = 0; i < m_attachments.size(); ++i) { - const VAttachment &item = m_attachments[i]; - QJsonObject attachmentItem; - attachmentItem[DirConfig::c_name] = item.m_name; - attachmentJson.append(attachmentItem); - } - - item[DirConfig::c_attachments] = attachmentJson; - - return item; -} - -bool VNoteFile::deleteFile(QString *p_errMsg) -{ - Q_ASSERT(!m_opened); - Q_ASSERT(parent()); - - bool ret = true; - - // Delete local images if it is Markdown. - if (m_docType == DocType::Markdown) { - if (!deleteInternalImages()) { - ret = false; - VUtils::addErrMsg(p_errMsg, tr("Fail to delete images of this note.")); - } - } - - // Delete attachments. - if (!deleteAttachments()) { - ret = false; - VUtils::addErrMsg(p_errMsg, tr("Fail to delete attachments of this note.")); - } - - // Delete the file. - QString filePath = fetchPath(); - if (VUtils::deleteFile(getNotebook(), filePath, false)) { - qDebug() << "deleted" << m_name << filePath; - } else { - ret = false; - VUtils::addErrMsg(p_errMsg, tr("Fail to delete the note file.")); - qWarning() << "fail to delete" << m_name << filePath; - } - - return ret; -} - -bool VNoteFile::deleteInternalImages() -{ - Q_ASSERT(parent() && m_docType == DocType::Markdown); - - QVector images = VUtils::fetchImagesFromMarkdownFile(this, - ImageLink::LocalRelativeInternal); - int deleted = 0; - for (int i = 0; i < images.size(); ++i) { - if (VUtils::deleteFile(getNotebook(), images[i].m_path, false)) { - ++deleted; - } - } - - qDebug() << "delete" << deleted << "images for" << m_name << fetchPath(); - - return deleted == images.size(); -} - -bool VNoteFile::addAttachment(const QString &p_file) -{ - if (p_file.isEmpty() || !QFileInfo::exists(p_file)) { - return false; - } - - QString folderPath = fetchAttachmentFolderPath(); - QString name = VUtils::fileNameFromPath(p_file); - Q_ASSERT(!name.isEmpty()); - // For attachments, we do not use complete base name. - // abc.tar.gz should be abc_001.tar.gz instead of abc.tar_001.gz. - name = VUtils::getFileNameWithSequence(folderPath, name, false); - QString destPath = QDir(folderPath).filePath(name); - if (!VUtils::copyFile(p_file, destPath, false)) { - return false; - } - - m_attachments.push_back(VAttachment(name)); - - if (!getDirectory()->updateFileConfig(this)) { - qWarning() << "fail to update config of file" << m_name - << "in directory" << fetchBasePath(); - return false; - } - - return true; -} - -QString VNoteFile::fetchAttachmentFolderPath() -{ - QString folderPath = QDir(fetchBasePath()).filePath(getNotebook()->getAttachmentFolder()); - if (m_attachmentFolder.isEmpty()) { - m_attachmentFolder = VUtils::getRandomFileName(folderPath); - } - - folderPath = QDir(folderPath).filePath(m_attachmentFolder); - if (!QFileInfo::exists(folderPath)) { - QDir dir; - if (!dir.mkpath(folderPath)) { - qWarning() << "fail to create attachment folder of notebook" << m_name << folderPath; - } - } - - return folderPath; -} - -bool VNoteFile::deleteAttachments(bool p_omitMissing) -{ - if (m_attachments.isEmpty()) { - return true; - } - - QVector attas; - for (int i = 0; i < m_attachments.size(); ++i) { - attas.push_back(m_attachments[i].m_name); - } - - return deleteAttachments(attas, p_omitMissing); -} - -bool VNoteFile::deleteAttachments(const QVector &p_names, - bool p_omitMissing) -{ - if (p_names.isEmpty()) { - return true; - } - - QDir dir(fetchAttachmentFolderPath()); - bool ret = true; - for (int i = 0; i < p_names.size(); ++i) { - int idx = findAttachment(p_names[i]); - if (idx == -1) { - ret = false; - continue; - } - - m_attachments.remove(idx); - - QString filePath = dir.filePath(p_names[i]); - if (p_omitMissing - && !QFileInfo::exists(filePath)) { - // The attachment file does not exist. We skip it to avoid error. - continue; - } - - if (!VUtils::deleteFile(getNotebook(), filePath, false)) { - ret = false; - qWarning() << "fail to delete attachment" << p_names[i] - << "for note" << m_name; - } - } - - // Delete the attachment folder if m_attachments is empty now. - if (m_attachments.isEmpty()) { - dir.cdUp(); - if (!dir.rmdir(m_attachmentFolder)) { - ret = false; - qWarning() << "fail to delete attachment folder" << m_attachmentFolder - << "for note" << m_name; - } - } - - if (!getDirectory()->updateFileConfig(this)) { - ret = false; - qWarning() << "fail to update config of file" << m_name - << "in directory" << fetchBasePath(); - } - - return ret; -} - -int VNoteFile::findAttachment(const QString &p_name, bool p_caseSensitive) -{ - const QString name = p_caseSensitive ? p_name : p_name.toLower(); - for (int i = 0; i < m_attachments.size(); ++i) { - QString attaName = p_caseSensitive ? m_attachments[i].m_name - : m_attachments[i].m_name.toLower(); - if (name == attaName) { - return i; - } - } - - return -1; -} - -bool VNoteFile::sortAttachments(const QVector &p_sortedIdx) -{ - V_ASSERT(m_opened); - V_ASSERT(p_sortedIdx.size() == m_attachments.size()); - - auto ori = m_attachments; - - for (int i = 0; i < p_sortedIdx.size(); ++i) { - m_attachments[i] = ori[p_sortedIdx[i]]; - } - - bool ret = true; - if (!getDirectory()->updateFileConfig(this)) { - qWarning() << "fail to reorder attachments in config" << p_sortedIdx; - m_attachments = ori; - ret = false; - } - - return ret; -} - -bool VNoteFile::renameAttachment(const QString &p_oldName, const QString &p_newName) -{ - int idx = findAttachment(p_oldName); - if (idx == -1) { - return false; - } - - QDir dir(fetchAttachmentFolderPath()); - if (!dir.rename(p_oldName, p_newName)) { - qWarning() << "fail to rename attachment file" << p_oldName << p_newName; - return false; - } - - m_attachments[idx].m_name = p_newName; - - if (!getDirectory()->updateFileConfig(this)) { - qWarning() << "fail to rename attachment in config" << p_oldName << p_newName; - - m_attachments[idx].m_name = p_oldName; - dir.rename(p_newName, p_oldName); - - return false; - } - - return true; -} - -QVector VNoteFile::checkAttachments() -{ - QVector missing; - - QDir dir(fetchAttachmentFolderPath()); - for (auto const & atta : m_attachments) { - QString file = dir.filePath(atta.m_name); - if (!QFileInfo::exists(file)) { - missing.push_back(atta.m_name); - } - } - - return missing; -} - -bool VNoteFile::deleteFile(VNoteFile *p_file, QString *p_errMsg) -{ - Q_ASSERT(!p_file->isOpened()); - - bool ret = true; - QString name = p_file->getName(); - QString path = p_file->fetchPath(); - - if (!p_file->deleteFile(p_errMsg)) { - qWarning() << "fail to delete file" << name << path; - ret = false; - } - - VDirectory *dir = p_file->getDirectory(); - Q_ASSERT(dir); - if (!dir->removeFile(p_file)) { - qWarning() << "fail to remove file from directory" << name << path; - VUtils::addErrMsg(p_errMsg, tr("Fail to remove the note from the folder configuration.")); - ret = false; - } - - delete p_file; - - return ret; -} - -bool VNoteFile::copyFile(VDirectory *p_destDir, - const QString &p_destName, - VNoteFile *p_file, - bool p_isCut, - VNoteFile **p_targetFile, - QString *p_errMsg) -{ - bool ret = true; - *p_targetFile = NULL; - int nrImageCopied = 0; - bool attachmentFolderCopied = false; - - QString srcPath = QDir::cleanPath(p_file->fetchPath()); - QString destPath = QDir::cleanPath(QDir(p_destDir->fetchPath()).filePath(p_destName)); - if (VUtils::equalPath(srcPath, destPath)) { - *p_targetFile = p_file; - return false; - } - - if (!p_destDir->isOpened()) { - VUtils::addErrMsg(p_errMsg, tr("Fail to open target folder.")); - return false; - } - - QString opStr = p_isCut ? tr("cut") : tr("copy"); - VDirectory *srcDir = p_file->getDirectory(); - DocType docType = p_file->getDocType(); - - Q_ASSERT(srcDir->isOpened()); - Q_ASSERT(docType == VUtils::docTypeFromName(p_destName)); - - // Images to be copied. - QVector images; - if (docType == DocType::Markdown) { - images = VUtils::fetchImagesFromMarkdownFile(p_file, - ImageLink::LocalRelativeInternal); - } - - // Attachments to be copied. - QString attaFolder = p_file->getAttachmentFolder(); - QString attaFolderPath; - if (!attaFolder.isEmpty()) { - attaFolderPath = p_file->fetchAttachmentFolderPath(); - } - - // Copy the note file. - if (!VUtils::copyFile(srcPath, destPath, p_isCut)) { - VUtils::addErrMsg(p_errMsg, tr("Fail to %1 the note file.").arg(opStr)); - qWarning() << "fail to" << opStr << "the note file" << srcPath << "to" << destPath; - return false; - } - - // Add file to VDirectory. - VNoteFile *destFile = NULL; - if (p_isCut) { - srcDir->removeFile(p_file); - p_file->setName(p_destName); - if (p_destDir->addFile(p_file, -1)) { - destFile = p_file; - } else { - destFile = NULL; - } - } else { - destFile = p_destDir->addFile(p_destName, -1); - } - - if (!destFile) { - VUtils::addErrMsg(p_errMsg, tr("Fail to add the note to target folder's configuration.")); - return false; - } - - // Copy images. - QDir parentDir(destFile->fetchBasePath()); - QSet processedImages; - for (int i = 0; i < images.size(); ++i) { - const ImageLink &link = images[i]; - if (processedImages.contains(link.m_path)) { - continue; - } - - processedImages.insert(link.m_path); - - if (!QFileInfo::exists(link.m_path)) { - VUtils::addErrMsg(p_errMsg, tr("Source image %1 does not exist.") - .arg(link.m_path)); - ret = false; - continue; - } - - QString imageFolder = VUtils::directoryNameFromPath(VUtils::basePathFromPath(link.m_path)); - QString destImagePath = QDir(parentDir.filePath(imageFolder)).filePath(VUtils::fileNameFromPath(link.m_path)); - - if (VUtils::equalPath(link.m_path, destImagePath)) { - VUtils::addErrMsg(p_errMsg, tr("Skip image with the same source and target path %1.") - .arg(link.m_path)); - ret = false; - continue; - } - - if (!VUtils::copyFile(link.m_path, destImagePath, p_isCut)) { - VUtils::addErrMsg(p_errMsg, tr("Fail to %1 image %2 to %3. " - "Please manually %1 it and modify the note.") - .arg(opStr).arg(link.m_path).arg(destImagePath)); - ret = false; - } else { - ++nrImageCopied; - qDebug() << opStr << "image" << link.m_path << "to" << destImagePath; - } - } - - // Copy attachment folder. - if (!attaFolderPath.isEmpty()) { - QDir dir(destFile->fetchBasePath()); - QString folderPath = dir.filePath(destFile->getNotebook()->getAttachmentFolder()); - attaFolder = VUtils::getDirNameWithSequence(folderPath, attaFolder); - folderPath = QDir(folderPath).filePath(attaFolder); - - // Copy attaFolderPath to folderPath. - if (!VUtils::copyDirectory(attaFolderPath, folderPath, p_isCut)) { - VUtils::addErrMsg(p_errMsg, tr("Fail to %1 attachments folder %2 to %3. " - "Please manually maintain it.") - .arg(opStr).arg(attaFolderPath).arg(folderPath)); - QVector emptyAttas; - destFile->setAttachments(emptyAttas); - ret = false; - } else { - attachmentFolderCopied = true; - - destFile->setAttachmentFolder(attaFolder); - if (!p_isCut) { - destFile->setAttachments(p_file->getAttachments()); - } - } - - if (!p_destDir->updateFileConfig(destFile)) { - VUtils::addErrMsg(p_errMsg, tr("Fail to update configuration of note %1.") - .arg(destFile->fetchPath())); - ret = false; - } - } - - qDebug() << "copyFile:" << p_file << "to" << destFile - << "copied_images:" << nrImageCopied - << "copied_attachments:" << attachmentFolderCopied; - - *p_targetFile = destFile; - return ret; -} - diff --git a/src/vnotefile.h b/src/vnotefile.h deleted file mode 100644 index 96d3a344..00000000 --- a/src/vnotefile.h +++ /dev/null @@ -1,168 +0,0 @@ -#ifndef VNOTEFILE_H -#define VNOTEFILE_H - -#include -#include - -#include "vfile.h" - -class VDirectory; -class VNotebook; - -// Structure for a note attachment. -struct VAttachment -{ - VAttachment() - { - } - - VAttachment(const QString &p_name) - : m_name(p_name) - { - } - - // File name of the attachment. - QString m_name; -}; - -class VNoteFile : public VFile -{ - Q_OBJECT -public: - VNoteFile(VDirectory *p_directory, - const QString &p_name, - FileType p_type, - bool p_modifiable, - QDateTime p_createdTimeUtc, - QDateTime p_modifiedTimeUtc, - const QString &p_attachmentFolder = "", - const QVector &p_attachments = QVector()); - - QString fetchPath() const Q_DECL_OVERRIDE; - - QString fetchBasePath() const Q_DECL_OVERRIDE; - - QString fetchImageFolderPath() const Q_DECL_OVERRIDE; - - bool useRelativeImageFolder() const Q_DECL_OVERRIDE; - - QString getImageFolderInLink() const Q_DECL_OVERRIDE; - - // Set the name of this file. - void setName(const QString &p_name); - - // Rename the name of this file in disk and config. - bool rename(const QString &p_name); - - VDirectory *getDirectory(); - - const VDirectory *getDirectory() const; - - VNotebook *getNotebook(); - - const VNotebook *getNotebook() const; - - QString getNotebookName() const; - - // Get the relative path related to the notebook. - QString fetchRelativePath() const; - - // Create a Json object from current instance. - QJsonObject toConfigJson() const; - - const QString &getAttachmentFolder() const; - - void setAttachmentFolder(const QString &p_folder); - - const QVector &getAttachments() const; - - void setAttachments(const QVector &p_attas); - - // Add @p_file as an attachment to this note. - bool addAttachment(const QString &p_file); - - // Fetch attachment folder path. - // Will create it if it does not exist. - QString fetchAttachmentFolderPath(); - - // Delete all the attachments. - // @p_omitMissing: omit the error if the attachment file does not exist. - bool deleteAttachments(bool p_omitMissing = false); - - // Delete attachments specified by @p_names. - // @p_omitMissing: omit the error if the attachment file does not exist. - bool deleteAttachments(const QVector &p_names, - bool p_omitMissing = false); - - // Reorder attachments in m_attachments by index. - bool sortAttachments(const QVector &p_sortedIdx); - - // Return the index of @p_name in m_attachments. - // -1 if not found. - int findAttachment(const QString &p_name, bool p_caseSensitive = true); - - // Rename attachment @p_oldName to @p_newName. - bool renameAttachment(const QString &p_oldName, const QString &p_newName); - - // Check if all the attachment files still exist. - // Return the missing attachments' names. - QVector checkAttachments(); - - // Create a VNoteFile from @p_json Json object. - static VNoteFile *fromJson(VDirectory *p_directory, - const QJsonObject &p_json, - FileType p_type, - bool p_modifiable); - - // Delete file @p_file including removing it from parent directory configuration - // and delete the file in disk. - // @p_file: should be a normal file with parent directory. - // @p_errMsg: if not NULL, it will contain error message if this function fails. - static bool deleteFile(VNoteFile *p_file, QString *p_errMsg = NULL); - - // Copy file @p_file to @p_destDir with new name @p_destName. - // Returns a file representing the destination file after copy/cut. - static bool copyFile(VDirectory *p_destDir, - const QString &p_destName, - VNoteFile *p_file, - bool p_isCut, - VNoteFile **p_targetFile, - QString *p_errMsg = NULL); - -private: - // Delete internal images of this file. - // Return true only when all internal images were deleted successfully. - bool deleteInternalImages(); - - // Delete this file in disk as well as all its images/attachments. - bool deleteFile(QString *p_msg = NULL); - - // Folder under the attachment folder of the notebook. - // Store all the attachments of current file. - QString m_attachmentFolder; - - // Attachments. - QVector m_attachments; -}; - -inline const QString &VNoteFile::getAttachmentFolder() const -{ - return m_attachmentFolder; -} - -inline void VNoteFile::setAttachmentFolder(const QString &p_folder) -{ - m_attachmentFolder = p_folder; -} - -inline const QVector &VNoteFile::getAttachments() const -{ - return m_attachments; -} - -inline void VNoteFile::setAttachments(const QVector &p_attas) -{ - m_attachments = p_attas; -} - -#endif // VNOTEFILE_H diff --git a/src/vopenedlistmenu.cpp b/src/vopenedlistmenu.cpp deleted file mode 100644 index 7dce1878..00000000 --- a/src/vopenedlistmenu.cpp +++ /dev/null @@ -1,273 +0,0 @@ -#include "vopenedlistmenu.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "veditwindow.h" -#include "vnotefile.h" -#include "vedittab.h" -#include "vdirectory.h" -#include "utils/vutils.h" -#include "vbuttonmenuitem.h" -#include "utils/vimnavigationforwidget.h" - -static const int c_cmdTime = 1 * 1000; - -static bool fileComp(const VOpenedListMenu::ItemInfo &a, - const VOpenedListMenu::ItemInfo &b) -{ - QString notebooka, notebookb; - if (a.file->getType() == FileType::Note) { - notebooka = dynamic_cast(a.file)->getNotebookName().toLower(); - } else { - notebooka = "EXTERNAL_FILES"; - } - - if (b.file->getType() == FileType::Note) { - notebookb = dynamic_cast(b.file)->getNotebookName().toLower(); - } else { - notebookb = "EXTERNAL_FILES"; - } - - if (notebooka < notebookb) { - return true; - } else if (notebooka > notebookb) { - return false; - } else { - QString patha = a.file->fetchBasePath(); - QString pathb = b.file->fetchBasePath(); -#if defined(Q_OS_WIN) - patha = patha.toLower(); - pathb = pathb.toLower(); -#endif - if (patha == pathb) { - return a.index < b.index; - } else { - return patha < pathb; - } - } -} - -VOpenedListMenu::VOpenedListMenu(VEditWindow *p_editWin) - : QMenu(p_editWin), - m_editWin(p_editWin), - m_cmdNum(0), - m_accepted(false) -{ - setToolTipsVisible(true); - - m_cmdTimer = new QTimer(this); - m_cmdTimer->setSingleShot(true); - m_cmdTimer->setInterval(c_cmdTime); - connect(m_cmdTimer, &QTimer::timeout, - this, &VOpenedListMenu::cmdTimerTimeout); - - connect(this, &QMenu::aboutToShow, - this, &VOpenedListMenu::updateOpenedList); - connect(this, &QMenu::triggered, - this, &VOpenedListMenu::handleItemTriggered); -} - -void VOpenedListMenu::updateOpenedList() -{ - // Regenerate the opened list. - m_seqActionMap.clear(); - clear(); - m_accepted = false; - - int curTab = m_editWin->currentIndex(); - int nrTab = m_editWin->count(); - QVector files(nrTab); - for (int i = 0; i < nrTab; ++i) { - files[i].file = m_editWin->getTab(i)->getFile(); - files[i].index = i; - } - - Q_ASSERT(!files.isEmpty()); - - std::sort(files.begin(), files.end(), fileComp); - - QString notebook; - const VDirectory *directory = NULL; - for (int i = 0; i < nrTab; ++i) { - QPointer file = files[i].file; - int index = files[i].index; - - // Whether add separator. - QString curNotebook; - const VDirectory *curDirectory = NULL; - if (file->getType() == FileType::Note) { - const VNoteFile *tmpFile = dynamic_cast((VFile *)file); - curNotebook = tmpFile->getNotebookName(); - curDirectory = tmpFile->getDirectory(); - } else { - curNotebook = "EXTERNAL_FILES"; - } - - QString separatorText; - if (curNotebook != notebook - || curDirectory != directory) { - notebook = curNotebook; - directory = curDirectory; - QString dirName; - if (directory) { - dirName = directory->getName(); - } - - if (dirName.isEmpty()) { - separatorText = QString("[%1]").arg(notebook); - } else { - separatorText = QString("[%1] %2").arg(notebook).arg(dirName); - } - - // Add label as separator. - QWidgetAction *wact = new QWidgetAction(this); - QLabel *label = new QLabel(separatorText); - label->setProperty("MenuSeparator", true); - wact->setDefaultWidget(label); - wact->setSeparator(true); - addAction(wact); - } - - // Append the separator text to the end of the first item as well. - QWidgetAction *wact = new QWidgetAction(this); - wact->setData(QVariant::fromValue(file)); - VButtonMenuItem *w = new VButtonMenuItem(wact, - m_editWin->tabIcon(index), - m_editWin->tabText(index), - separatorText, - this); - w->setToolTip(generateDescription(file)); - wact->setDefaultWidget(w); - - if (index == curTab) { - QFont boldFont = w->font(); - boldFont.setBold(true); - w->setFont(boldFont); - - w->setFocus(); - } - - addAction(wact); - m_seqActionMap[index + c_tabSequenceBase] = wact; - } -} - -QString VOpenedListMenu::generateDescription(const VFile *p_file) const -{ - if (!p_file) { - return ""; - } - - // [Notebook]path - if (p_file->getType() == FileType::Note) { - const VNoteFile *tmpFile = dynamic_cast(p_file); - return QString("[%1] %2").arg(tmpFile->getNotebookName()).arg(tmpFile->fetchPath()); - } else { - return QString("%1").arg(p_file->fetchPath()); - } -} - -void VOpenedListMenu::handleItemTriggered(QAction *p_action) -{ - if (p_action) { - QPointer file = p_action->data().value>(); - if (file) { - m_accepted = true; - emit fileTriggered(file); - } - } - - hide(); -} - -void VOpenedListMenu::keyPressEvent(QKeyEvent *p_event) -{ - if (VimNavigationForWidget::injectKeyPressEventForVim(this, - p_event)) { - m_cmdTimer->stop(); - m_cmdNum = 0; - return; - } - - int key = p_event->key(); - switch (key) { - case Qt::Key_0: - case Qt::Key_1: - case Qt::Key_2: - case Qt::Key_3: - case Qt::Key_4: - case Qt::Key_5: - case Qt::Key_6: - case Qt::Key_7: - case Qt::Key_8: - case Qt::Key_9: - { - addDigit(key - Qt::Key_0); - return; - } - - default: - m_cmdTimer->stop(); - m_cmdNum = 0; - break; - } - - QMenu::keyPressEvent(p_event); -} - -void VOpenedListMenu::cmdTimerTimeout() -{ - if (m_cmdNum > 0) { - triggerItem(m_cmdNum); - m_cmdNum = 0; - } -} - -void VOpenedListMenu::addDigit(int p_digit) -{ - V_ASSERT(p_digit >= 0 && p_digit <= 9); - m_cmdTimer->stop(); - m_cmdNum = m_cmdNum * 10 + p_digit; - - int totalItem = m_seqActionMap.size(); - // Try to trigger it ASAP. - if (m_cmdNum > 0) { - if (getNumOfDigit(m_cmdNum) == getNumOfDigit(totalItem)) { - triggerItem(m_cmdNum); - m_cmdNum = 0; - return; - } - } - - m_cmdTimer->start(); -} - -int VOpenedListMenu::getNumOfDigit(int p_num) -{ - int nrDigit = 1; - while (true) { - p_num /= 10; - if (p_num == 0) { - return nrDigit; - } else { - ++nrDigit; - } - } -} - -void VOpenedListMenu::triggerItem(int p_seq) -{ - auto it = m_seqActionMap.find(p_seq); - if (it != m_seqActionMap.end()) { - QAction *act = it.value(); - act->trigger(); - hide(); - } -} diff --git a/src/vopenedlistmenu.h b/src/vopenedlistmenu.h deleted file mode 100644 index 4084cf70..00000000 --- a/src/vopenedlistmenu.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef VOPENEDLISTMENU_H -#define VOPENEDLISTMENU_H - -#include -#include - -class VEditWindow; -class VFile; -class QAction; -class QKeyEvent; -class QTimer; - -class VOpenedListMenu : public QMenu -{ - Q_OBJECT -public: - struct ItemInfo { - VFile *file; - int index; - }; - - explicit VOpenedListMenu(VEditWindow *p_editWin); - - bool isAccepted() const; - -protected: - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - -signals: - void fileTriggered(VFile *p_file); - -private slots: - void updateOpenedList(); - void handleItemTriggered(QAction *p_action); - void cmdTimerTimeout(); - -private: - QString generateDescription(const VFile *p_file) const; - void addDigit(int p_digit); - int getNumOfDigit(int p_num); - void triggerItem(int p_seq); - - VEditWindow *m_editWin; - - // The number user pressed. - int m_cmdNum; - - QTimer *m_cmdTimer; - QMap m_seqActionMap; - - // Whether the menu is accepted or rejected. - bool m_accepted; -}; - -inline bool VOpenedListMenu::isAccepted() const -{ - return m_accepted; -} -#endif // VOPENEDLISTMENU_H diff --git a/src/vorphanfile.cpp b/src/vorphanfile.cpp deleted file mode 100644 index a0cf9543..00000000 --- a/src/vorphanfile.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include "vorphanfile.h" -#include -#include -#include -#include -#include "utils/vutils.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -VOrphanFile::VOrphanFile(QObject *p_parent, - const QString &p_path, - bool p_modifiable, - bool p_systemFile) - : VFile(p_parent, - VUtils::fileNameFromPath(p_path), - FileType::Orphan, - p_modifiable, - QDateTime(), - QDateTime()), - m_path(p_path), - m_systemFile(p_systemFile) -{ -} - -QString VOrphanFile::fetchPath() const -{ - return m_path; -} - -QString VOrphanFile::fetchBasePath() const -{ - return VUtils::basePathFromPath(m_path); -} - -QString VOrphanFile::fetchImageFolderPath() const -{ - QString folder = m_imageFolder; - if (m_imageFolder.isEmpty()) { - folder = g_config->getImageFolderExt(); - } - - QFileInfo fi(folder); - if (fi.isAbsolute()) { - return folder; - } else { - return QDir(fetchBasePath()).filePath(folder); - } -} - -bool VOrphanFile::useRelativeImageFolder() const -{ - QString folder = m_imageFolder; - if (m_imageFolder.isEmpty()) { - folder = g_config->getImageFolderExt(); - } - - return !QFileInfo(folder).isAbsolute(); -} - -QString VOrphanFile::getImageFolderInLink() const -{ - QString folder = m_imageFolder; - if (m_imageFolder.isEmpty()) { - folder = g_config->getImageFolderExt(); - } - - return folder; -} - -QString VOrphanFile::fetchRecycleBinFolderPath() const -{ - QString folder = m_recycleBinFolder; - if (m_recycleBinFolder.isEmpty()) { - folder = g_config->getRecycleBinFolderExt(); - } - - QFileInfo fi(folder); - if (fi.isAbsolute()) { - return folder; - } else { - return QDir(fetchBasePath()).filePath(folder); - } -} diff --git a/src/vorphanfile.h b/src/vorphanfile.h deleted file mode 100644 index 6d4b851a..00000000 --- a/src/vorphanfile.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef VORPHANFILE_H -#define VORPHANFILE_H - -#include "vfile.h" - -// VOrphanFile is a file not belonging to any notebooks or directories. -// Such as external files, system files. -// It uses the file path to locate and identify a file. -class VOrphanFile : public VFile -{ - Q_OBJECT -public: - VOrphanFile(QObject *p_parent, - const QString &p_path, - bool p_modifiable, - bool p_systemFile = false); - - QString fetchPath() const Q_DECL_OVERRIDE; - - QString fetchBasePath() const Q_DECL_OVERRIDE; - - QString fetchImageFolderPath() const Q_DECL_OVERRIDE; - - // Whether use a relative image folder. - bool useRelativeImageFolder() const Q_DECL_OVERRIDE; - - // Return the image folder part in an image link. - QString getImageFolderInLink() const Q_DECL_OVERRIDE; - - // Return image folder config. - const QString getImageFolder() const; - - // Set the image folder config. - void setImageFolder(const QString &p_path); - - bool isSystemFile() const; - - // Get the recycle bin folder for this file. - QString fetchRecycleBinFolderPath() const; - -private: - // Full path of this file. - QString m_path; - - // Image folder path of this file. - // It could be an absolute or relative path. - // Empty to use the global default config. - // Valid only within a session. - QString m_imageFolder; - - // Recycle bin forlder. - // May be absolute or relative path. - // Empty to use the global default config. - // Valid only within a session. - QString m_recycleBinFolder; - - // Whether it is a system internal file. - bool m_systemFile; -}; - -inline const QString VOrphanFile::getImageFolder() const -{ - return m_imageFolder; -} - -inline void VOrphanFile::setImageFolder(const QString &p_path) -{ - m_imageFolder = p_path; -} - -inline bool VOrphanFile::isSystemFile() const -{ - return m_systemFile; -} - -#endif // VORPHANFILE_H diff --git a/src/voutline.cpp b/src/voutline.cpp deleted file mode 100644 index efda9a44..00000000 --- a/src/voutline.cpp +++ /dev/null @@ -1,243 +0,0 @@ -#include -#include -#include -#include -#include -#include "voutline.h" -#include "utils/vutils.h" -#include "vnote.h" -#include "vfile.h" - -extern VNote *g_vnote; - -VOutline::VOutline(QWidget *parent) - : QTreeWidget(parent), - VNavigationMode(), - m_muted(false) -{ - setColumnCount(1); - setHeaderHidden(true); - setSelectionMode(QAbstractItemView::SingleSelection); - setAttribute(Qt::WA_MacShowFocusRect, false); - - // TODO: jump to the header when user click the same item twice. - connect(this, &VOutline::currentItemChanged, - this, &VOutline::handleCurrentItemChanged); -} - -void VOutline::updateOutline(const VTableOfContent &p_outline) -{ - if (p_outline == m_outline) { - return; - } - - // Clear current header - m_currentHeader.clear(); - - m_outline = p_outline; - - updateTreeFromOutline(); - - expandTree(); -} - -void VOutline::updateTreeFromOutline() -{ - clear(); - - if (m_outline.isEmpty()) { - return; - } - - const QVector &headers = m_outline.getTable(); - int idx = 0; - updateTreeByLevel(headers, idx, NULL, NULL, 1); -} - -void VOutline::updateTreeByLevel(const QVector &headers, - int &index, - QTreeWidgetItem *parent, - QTreeWidgetItem *last, - int level) -{ - while (index < headers.size()) { - const VTableOfContentItem &header = headers[index]; - QTreeWidgetItem *item; - if (header.m_level == level) { - if (parent) { - item = new QTreeWidgetItem(parent); - } else { - item = new QTreeWidgetItem(this); - } - - fillItem(item, header); - - last = item; - ++index; - } else if (header.m_level < level) { - return; - } else { - updateTreeByLevel(headers, index, last, NULL, level + 1); - } - } -} - -void VOutline::fillItem(QTreeWidgetItem *p_item, const VTableOfContentItem &p_header) -{ - p_item->setData(0, Qt::UserRole, p_header.m_index); - p_item->setText(0, p_header.m_name); - p_item->setToolTip(0, p_header.m_name); - - if (p_header.isEmpty()) { - p_item->setForeground(0, QColor("grey")); - } -} - -void VOutline::expandTree() -{ - if (topLevelItemCount() == 0) { - return; - } - - expandAll(); -} - -void VOutline::handleCurrentItemChanged(QTreeWidgetItem *p_curItem, - QTreeWidgetItem * p_preItem) -{ - Q_UNUSED(p_preItem); - - if (!p_curItem) { - return; - } - - const VTableOfContentItem *header = getHeaderFromItem(p_curItem); - Q_ASSERT(header); - m_currentHeader.update(m_outline.getFile(), header->m_index); - - if (!header->isEmpty() && !m_muted) { - emit outlineItemActivated(m_currentHeader); - } -} - -void VOutline::updateCurrentHeader(const VHeaderPointer &p_header) -{ - if (p_header == m_currentHeader - || !m_outline.isMatched(p_header)) { - return; - } - - // Item change should not emit the signal. - m_muted = true; - m_currentHeader = p_header; - selectHeader(m_currentHeader); - m_muted = false; -} - -void VOutline::selectHeader(const VHeaderPointer &p_header) -{ - setCurrentItem(NULL); - - if (!m_outline.getItem(p_header)) { - return; - } - - int nrTop = topLevelItemCount(); - for (int i = 0; i < nrTop; ++i) { - if (selectHeaderOne(topLevelItem(i), p_header)) { - return; - } - } -} - -bool VOutline::selectHeaderOne(QTreeWidgetItem *p_item, const VHeaderPointer &p_header) -{ - if (!p_item) { - return false; - } - - const VTableOfContentItem *header = getHeaderFromItem(p_item); - if (!header) { - return false; - } - - if (header->isMatched(p_header)) { - setCurrentItem(p_item); - return true; - } - - int nrChild = p_item->childCount(); - for (int i = 0; i < nrChild; ++i) { - if (selectHeaderOne(p_item->child(i), p_header)) { - return true; - } - } - - return false; -} - -void VOutline::keyPressEvent(QKeyEvent *event) -{ - int key = event->key(); - int modifiers = event->modifiers(); - - switch (key) { - case Qt::Key_Return: - { - QTreeWidgetItem *item = currentItem(); - if (item) { - item->setExpanded(!item->isExpanded()); - } - break; - } - - case Qt::Key_J: - { - if (modifiers == Qt::ControlModifier) { - event->accept(); - QKeyEvent *downEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Down, - Qt::NoModifier); - QCoreApplication::postEvent(this, downEvent); - return; - } - break; - } - - case Qt::Key_K: - { - if (modifiers == Qt::ControlModifier) { - event->accept(); - QKeyEvent *upEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Up, - Qt::NoModifier); - QCoreApplication::postEvent(this, upEvent); - return; - } - break; - } - - default: - break; - } - - QTreeWidget::keyPressEvent(event); -} - -void VOutline::showNavigation() -{ - VNavigationMode::showNavigation(this); -} - -bool VOutline::handleKeyNavigation(int p_key, bool &p_succeed) -{ - static bool secondKey = false; - return VNavigationMode::handleKeyNavigation(this, - secondKey, - p_key, - p_succeed); -} - -const VTableOfContentItem *VOutline::getHeaderFromItem(QTreeWidgetItem *p_item) const -{ - int index = p_item->data(0, Qt::UserRole).toInt(); - return m_outline.getItem(index); -} diff --git a/src/voutline.h b/src/voutline.h deleted file mode 100644 index 3f21afd2..00000000 --- a/src/voutline.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef VOUTLINE_H -#define VOUTLINE_H - -#include -#include -#include -#include -#include "vtableofcontent.h" -#include "vnavigationmode.h" - -class QLabel; - -// Display table of content as a tree and enable user to click an item to -// jump to that header. -class VOutline : public QTreeWidget, public VNavigationMode -{ - Q_OBJECT -public: - VOutline(QWidget *parent = 0); - - // Implementations for VNavigationMode. - void showNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - -signals: - // Emit when current item changed by user and header of that item is not empty. - // Do not worry about infinite recursion. - void outlineItemActivated(const VHeaderPointer &p_header); - -public slots: - // Called to update outline and the tree. - // Just clear the tree if @p_outline is empty. - void updateOutline(const VTableOfContent &p_outline); - - // Called to update current header in the tree. - // Will not emit outlineItemActivated(). - void updateCurrentHeader(const VHeaderPointer &p_header); - -protected: - void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; - -private slots: - // Handle current item change even of the tree. - // Do not response if m_muted is true. - void handleCurrentItemChanged(QTreeWidgetItem *p_curItem, QTreeWidgetItem *p_preItem); - -private: - // Update tree according to outline. - void updateTreeFromOutline(); - - // @index: the index in @headers. - void updateTreeByLevel(const QVector &headers, - int &index, - QTreeWidgetItem *parent, - QTreeWidgetItem *last, - int level); - - void expandTree(); - - // Set the item corresponding to @p_header as current item. - void selectHeader(const VHeaderPointer &p_header); - - bool selectHeaderOne(QTreeWidgetItem *p_item, const VHeaderPointer &p_header); - - // Fill the info of @p_item. - void fillItem(QTreeWidgetItem *p_item, const VTableOfContentItem &p_header); - - // Return NULL if no corresponding header in outline. - const VTableOfContentItem *getHeaderFromItem(QTreeWidgetItem *p_item) const; - - VTableOfContent m_outline; - - VHeaderPointer m_currentHeader; - - // When true, won't emit outlineItemActivated(). - bool m_muted; -}; - -#endif // VOUTLINE_H diff --git a/src/vpalette.cpp b/src/vpalette.cpp deleted file mode 100644 index b8ea0180..00000000 --- a/src/vpalette.cpp +++ /dev/null @@ -1,237 +0,0 @@ -#include "vpalette.h" - -#include -#include -#include -#include -#include - -#include "utils/vutils.h" - -VPalette::VPalette(const QString &p_file) -{ - init(p_file); -} - -void VPalette::init(const QString &p_file) -{ - m_file = QFileInfo(p_file).absoluteFilePath(); - - QSettings settings(p_file, QSettings::IniFormat); - m_data = getPaletteMetaData(m_file); - initPaleteFromSettings(&settings, "phony"); - initPaleteFromSettings(&settings, "soft_defined"); - initPaleteFromSettings(&settings, "widgets"); - - qDebug() << "theme file" << m_file << m_data.toString(); -} - -void VPalette::initPaleteFromSettings(QSettings *p_settings, const QString &p_group) -{ - QRegExp reg("@(\\w+)"); - - p_settings->beginGroup(p_group); - // Used to store undefined pairs. - QHash undefined; - QStringList keys = p_settings->childKeys(); - for (auto const & key : keys) { - if (key.isEmpty()) { - continue; - } - - QString val = p_settings->value(key).toString(); - if (reg.exactMatch(val)) { - auto it = m_palette.find(reg.cap(1)); - if (it != m_palette.end()) { - val = it.value(); - } else { - undefined.insert(key, reg.cap(1)); - continue; - } - } - - m_palette.insert(key, val); - } - - // Handle definition: a=@b b=@c c=red. - int iter = 0; - while (!undefined.isEmpty()) { - if (iter >= undefined.size()) { - qWarning() << "cyclic palette definitions found" << undefined; - break; - } - - for (auto it = undefined.begin(); it != undefined.end();) { - auto pit = m_palette.find(it.value()); - if (pit != m_palette.end()) { - m_palette.insert(it.key(), pit.value()); - iter = 0; - it = undefined.erase(it); - } else { - ++iter; - ++it; - } - } - } - - p_settings->endGroup(); -} - -QString VPalette::color(const QString &p_name) const -{ - auto it = m_palette.find(p_name); - if (it != m_palette.end()) { - return it.value(); - } - - return QString(); -} - -void VPalette::fillStyle(QString &p_text) const -{ - // Cap(2) is the string to be replaced. - QRegExp reg("(\\s|:)@(\\w+)(?=\\W)"); - - int pos = 0; - while (pos < p_text.size()) { - int idx = p_text.indexOf(reg, pos); - if (idx == -1) { - break; - } - - QString name = reg.cap(2); - QString val = color(name); - - if (val.isEmpty()) { - pos = idx + reg.matchedLength(); - } else { - pos = idx + reg.matchedLength() + val.size() - name.size() - 1; - p_text.replace(idx + reg.cap(1).size(), name.size() + 1, val); - } - } -} - -QString VPalette::fetchQtStyleSheet() const -{ - QString style = VUtils::readFileFromDisk(m_data.m_qssFile); - fillStyle(style); - fillAbsoluteUrl(style); - - return style; -} - -void VPalette::fillAbsoluteUrl(QString &p_style) const -{ - // Cap(2) is the string to be replaced. - QRegExp reg("(\\s|:)url\\(([^\\(\\)]+)\\)(?=\\W)"); - int literalSize = QString("url(").size(); - QDir dir(VUtils::basePathFromPath(m_file)); - - int pos = 0; - while (pos < p_style.size()) { - int idx = p_style.indexOf(reg, pos); - if (idx == -1) { - break; - } - - QString url = reg.cap(2); - QString abUrl = dir.filePath(url); - pos = idx + reg.matchedLength() + abUrl.size() - url.size(); - p_style.replace(idx + reg.cap(1).size() + literalSize, url.size(), abUrl); - } -} - -QMap VPalette::editorStylesFromThemes(const QList &p_themeFiles) -{ - QMap styles; - for (auto const & theme : p_themeFiles) { - QString value = getPaletteMetaData(theme).m_mdhlFile; - if (!value.isEmpty()) { - styles.insert(themeName(theme) + "/" + QFileInfo(value).completeBaseName(), value); - } - } - - return styles; -} - -QMap VPalette::cssStylesFromThemes(const QList &p_themeFiles) -{ - QMap styles; - for (auto const & theme : p_themeFiles) { - QString value = getPaletteMetaData(theme).m_cssFile; - if (!value.isEmpty()) { - styles.insert(themeName(theme) + "/" + QFileInfo(value).completeBaseName(), value); - } - } - - return styles; -} - -QMap VPalette::codeBlockCssStylesFromThemes(const QList &p_themeFiles) -{ - QMap styles; - for (auto const & theme : p_themeFiles) { - QString value = getPaletteMetaData(theme).m_codeBlockCssFile; - if (!value.isEmpty()) { - styles.insert(themeName(theme) + "/" + QFileInfo(value).completeBaseName(), value); - } - } - - return styles; -} - -VPaletteMetaData VPalette::getPaletteMetaData(const QString &p_paletteFile) -{ - VPaletteMetaData data; - - QSettings settings(p_paletteFile, QSettings::IniFormat); - QDir dir(VUtils::basePathFromPath(QFileInfo(p_paletteFile).absoluteFilePath())); - - settings.beginGroup("metadata"); - QString val = settings.value("qss_file").toString(); - if (!val.isEmpty()) { - data.m_qssFile = dir.filePath(val); - } - - val = settings.value("mdhl_file").toString(); - if (!val.isEmpty()) { - data.m_mdhlFile = dir.filePath(val); - } - - val = settings.value("css_file").toString(); - if (!val.isEmpty()) { - data.m_cssFile = dir.filePath(val); - } - - val = settings.value("codeblock_css_file").toString(); - if (!val.isEmpty()) { - data.m_codeBlockCssFile = dir.filePath(val); - } - - settings.endGroup(); - - return data; -} - -QString VPalette::themeName(const QString &p_paletteFile) -{ - return QFileInfo(p_paletteFile).completeBaseName(); -} - -QString VPalette::themeEditorStyle(const QString &p_paletteFile) -{ - VPaletteMetaData data = getPaletteMetaData(p_paletteFile); - return themeName(p_paletteFile) + "/" + QFileInfo(data.m_mdhlFile).completeBaseName(); -} - -QString VPalette::themeCssStyle(const QString &p_paletteFile) -{ - VPaletteMetaData data = getPaletteMetaData(p_paletteFile); - return themeName(p_paletteFile) + "/" + QFileInfo(data.m_cssFile).completeBaseName(); -} - -QString VPalette::themeCodeBlockCssStyle(const QString &p_paletteFile) -{ - VPaletteMetaData data = getPaletteMetaData(p_paletteFile); - return themeName(p_paletteFile) + "/" + QFileInfo(data.m_codeBlockCssFile).completeBaseName(); -} diff --git a/src/vpalette.h b/src/vpalette.h deleted file mode 100644 index d79493cd..00000000 --- a/src/vpalette.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef VPALETTE_H -#define VPALETTE_H - -#include -#include -#include - -class QSettings; - -struct VPaletteMetaData -{ - // These are all file PATH, not name. - QString m_qssFile; - QString m_mdhlFile; - QString m_cssFile; - QString m_codeBlockCssFile; - - QString toString() const - { - return QString("palette metadata qss=%1 mdhl=%2 css=%3 codeBlockCss=%4") - .arg(m_qssFile) - .arg(m_mdhlFile) - .arg(m_cssFile) - .arg(m_codeBlockCssFile); - } -}; - - -class VPalette -{ -public: - explicit VPalette(const QString &p_file); - - QString color(const QString &p_name) const; - - // Read QSS file. - QString fetchQtStyleSheet() const; - - // Fill "@xxx" in @p_text with corresponding style. - void fillStyle(QString &p_text) const; - - // Read themes and return the mappings of editor styles. - static QMap editorStylesFromThemes(const QList &p_themeFiles); - - // Read themes and return the mappings of css styles. - static QMap cssStylesFromThemes(const QList &p_themeFiles); - - // Read themes and return the mappings of css styles. - static QMap codeBlockCssStylesFromThemes(const QList &p_themeFiles); - - static VPaletteMetaData getPaletteMetaData(const QString &p_paletteFile); - - // Return the name of the theme. - static QString themeName(const QString &p_paletteFile); - - // Return the name of the editor style of the theme. - static QString themeEditorStyle(const QString &p_paletteFile); - - // Return the name of the css style of the theme. - static QString themeCssStyle(const QString &p_paletteFile); - - // Return the name of the css style of the theme. - static QString themeCodeBlockCssStyle(const QString &p_paletteFile); - -private: - void init(const QString &p_file); - - void initPaleteFromSettings(QSettings *p_settings, const QString &p_group); - - void fillAbsoluteUrl(QString &p_style) const; - - // File path of the palette file. - QString m_file; - - QHash m_palette; - - VPaletteMetaData m_data; -}; - -#endif // VPALETTE_H diff --git a/src/vplaintextedit.cpp b/src/vplaintextedit.cpp deleted file mode 100644 index 7d33d463..00000000 --- a/src/vplaintextedit.cpp +++ /dev/null @@ -1,602 +0,0 @@ -#include "vplaintextedit.h" - -#include -#include -#include -#include -#include -#include - -#include "vimageresourcemanager.h" - - -const int VPlainTextEdit::c_minimumImageWidth = 100; - -enum class BlockState -{ - Normal = 0, - CodeBlockStart, - CodeBlock, - CodeBlockEnd, - Comment -}; - - -VPlainTextEdit::VPlainTextEdit(QWidget *p_parent) - : QPlainTextEdit(p_parent), - m_imageMgr(NULL), - m_blockImageEnabled(false), - m_imageWidthConstrainted(false), - m_maximumImageWidth(INT_MAX) -{ - init(); -} - -VPlainTextEdit::VPlainTextEdit(const QString &p_text, QWidget *p_parent) - : QPlainTextEdit(p_text, p_parent), - m_imageMgr(NULL), - m_blockImageEnabled(false), - m_imageWidthConstrainted(false), - m_maximumImageWidth(INT_MAX) -{ - init(); -} - -VPlainTextEdit::~VPlainTextEdit() -{ - if (m_imageMgr) { - delete m_imageMgr; - } -} - -void VPlainTextEdit::init() -{ - m_lineNumberType = LineNumberType::None; - - m_imageMgr = new VImageResourceManager(); - - QTextDocument *doc = document(); - QPlainTextDocumentLayout *layout = new VPlainTextDocumentLayout(doc, - m_imageMgr, - m_blockImageEnabled); - doc->setDocumentLayout(layout); - - m_lineNumberArea = new VLineNumberArea(this, - document(), - fontMetrics().width(QLatin1Char('8')), - fontMetrics().height(), - this); - connect(document(), &QTextDocument::blockCountChanged, - this, &VPlainTextEdit::updateLineNumberAreaMargin); - connect(this, &QPlainTextEdit::textChanged, - this, &VPlainTextEdit::updateLineNumberArea); - connect(verticalScrollBar(), &QScrollBar::valueChanged, - this, &VPlainTextEdit::updateLineNumberArea); - connect(this, &QPlainTextEdit::cursorPositionChanged, - this, &VPlainTextEdit::updateLineNumberArea); -} - -void VPlainTextEdit::updateBlockImages(const QVector &p_blocksInfo) -{ - if (m_blockImageEnabled) { - m_imageMgr->updateBlockInfos(p_blocksInfo, m_maximumImageWidth); - - update(); - } -} - -void VPlainTextEdit::clearBlockImages() -{ - m_imageMgr->clear(); -} - -bool VPlainTextEdit::containsImage(const QString &p_imageName) const -{ - return m_imageMgr->contains(p_imageName); -} - -void VPlainTextEdit::addImage(const QString &p_imageName, const QPixmap &p_image) -{ - if (m_blockImageEnabled) { - m_imageMgr->addImage(p_imageName, p_image); - } -} - -static void fillBackground(QPainter *p, - const QRectF &rect, - QBrush brush, - const QRectF &gradientRect = QRectF()) -{ - p->save(); - if (brush.style() >= Qt::LinearGradientPattern - && brush.style() <= Qt::ConicalGradientPattern) { - if (!gradientRect.isNull()) { - QTransform m = QTransform::fromTranslate(gradientRect.left(), - gradientRect.top()); - m.scale(gradientRect.width(), - gradientRect.height()); - brush.setTransform(m); - const_cast(brush.gradient())->setCoordinateMode(QGradient::LogicalMode); - } - } else { - p->setBrushOrigin(rect.topLeft()); - } - - p->fillRect(rect, brush); - p->restore(); -} - -void VPlainTextEdit::paintEvent(QPaintEvent *p_event) -{ - QPainter painter(viewport()); - QPointF offset(contentOffset()); - - QRect er = p_event->rect(); - QRect viewportRect = viewport()->rect(); - - bool editable = !isReadOnly(); - - QTextBlock block = firstVisibleBlock(); - qreal maximumWidth = document()->documentLayout()->documentSize().width(); - - // Set a brush origin so that the WaveUnderline knows where the wave started. - painter.setBrushOrigin(offset); - - // Keep right margin clean from full-width selection. - int maxX = offset.x() + qMax((qreal)viewportRect.width(), maximumWidth) - - document()->documentMargin(); - er.setRight(qMin(er.right(), maxX)); - painter.setClipRect(er); - - QAbstractTextDocumentLayout::PaintContext context = getPaintContext(); - - while (block.isValid()) { - QRectF r = blockBoundingRect(block).translated(offset); - QTextLayout *layout = block.layout(); - - if (!block.isVisible()) { - offset.ry() += r.height(); - block = block.next(); - continue; - } - - if (r.bottom() >= er.top() && r.top() <= er.bottom()) { - QTextBlockFormat blockFormat = block.blockFormat(); - QBrush bg = blockFormat.background(); - if (bg != Qt::NoBrush) { - QRectF contentsRect = r; - contentsRect.setWidth(qMax(r.width(), maximumWidth)); - fillBackground(&painter, contentsRect, bg); - } - - QVector selections; - int blpos = block.position(); - int bllen = block.length(); - for (int i = 0; i < context.selections.size(); ++i) { - const QAbstractTextDocumentLayout::Selection &range = context.selections.at(i); - const int selStart = range.cursor.selectionStart() - blpos; - const int selEnd = range.cursor.selectionEnd() - blpos; - if (selStart < bllen - && selEnd > 0 - && selEnd > selStart) { - QTextLayout::FormatRange o; - o.start = selStart; - o.length = selEnd - selStart; - o.format = range.format; - selections.append(o); - } else if (!range.cursor.hasSelection() - && range.format.hasProperty(QTextFormat::FullWidthSelection) - && block.contains(range.cursor.position())) { - // For full width selections we don't require an actual selection, just - // a position to specify the line. That's more convenience in usage. - QTextLayout::FormatRange o; - QTextLine l = layout->lineForTextPosition(range.cursor.position() - blpos); - o.start = l.textStart(); - o.length = l.textLength(); - if (o.start + o.length == bllen - 1) { - ++o.length; // include newline - } - - o.format = range.format; - selections.append(o); - } - } - - bool drawCursor = (editable - || (textInteractionFlags() & Qt::TextSelectableByKeyboard)) - && context.cursorPosition >= blpos - && context.cursorPosition < blpos + bllen; - - bool drawCursorAsBlock = drawCursor && overwriteMode() ; - if (drawCursorAsBlock) { - if (context.cursorPosition == blpos + bllen - 1) { - drawCursorAsBlock = false; - } else { - QTextLayout::FormatRange o; - o.start = context.cursorPosition - blpos; - o.length = 1; - o.format.setForeground(palette().base()); - o.format.setBackground(palette().text()); - selections.append(o); - } - } - - if (!placeholderText().isEmpty() - && document()->isEmpty() - && layout->preeditAreaText().isEmpty()) { - QColor col = palette().text().color(); - col.setAlpha(128); - painter.setPen(col); - const int margin = int(document()->documentMargin()); - painter.drawText(r.adjusted(margin, 0, 0, 0), - Qt::AlignTop | Qt::TextWordWrap, - placeholderText()); - } else { - layout->draw(&painter, offset, selections, er); - } - - if ((drawCursor && !drawCursorAsBlock) - || (editable - && context.cursorPosition < -1 - && !layout->preeditAreaText().isEmpty())) { - int cpos = context.cursorPosition; - if (cpos < -1) { - cpos = layout->preeditAreaPosition() - (cpos + 2); - } else { - cpos -= blpos; - } - - layout->drawCursor(&painter, offset, cpos, cursorWidth()); - } - - // Draw preview image of this block if there is one. - drawImageOfBlock(block, &painter, r); - } - - offset.ry() += r.height(); - if (offset.y() > viewportRect.height()) { - break; - } - - block = block.next(); - } - - if (backgroundVisible() - && !block.isValid() - && offset.y() <= er.bottom() - && (centerOnScroll() - || verticalScrollBar()->maximum() == verticalScrollBar()->minimum())) { - painter.fillRect(QRect(QPoint((int)er.left(), - (int)offset.y()), - er.bottomRight()), - palette().background()); - } -} - -void VPlainTextEdit::drawImageOfBlock(const QTextBlock &p_block, - QPainter *p_painter, - const QRectF &p_blockRect) -{ - if (!m_blockImageEnabled) { - return; - } - - const VBlockImageInfo *info = m_imageMgr->findImageInfoByBlock(p_block.blockNumber()); - if (!info) { - return; - } - - const QPixmap *image = m_imageMgr->findImage(info->m_imageName); - if (!image) { - return; - } - - int oriHeight = originalBlockBoundingRect(p_block).height(); - bool noMargin = (info->m_margin + info->m_imageWidth > m_maximumImageWidth); - int margin = noMargin ? 0 : info->m_margin; - QRect tmpRect(p_blockRect.toRect()); - QRect targetRect(tmpRect.x() + margin, - tmpRect.y() + oriHeight, - info->m_imageWidth, - qMax(info->m_imageHeight, tmpRect.height() - oriHeight)); - - p_painter->drawPixmap(targetRect, *image); - - auto *layout = getLayout(); - emit layout->documentSizeChanged(layout->documentSize()); -} - -QRectF VPlainTextEdit::originalBlockBoundingRect(const QTextBlock &p_block) const -{ - return getLayout()->QPlainTextDocumentLayout::blockBoundingRect(p_block); -} - -void VPlainTextEdit::setBlockImageEnabled(bool p_enabled) -{ - if (m_blockImageEnabled == p_enabled) { - return; - } - - m_blockImageEnabled = p_enabled; - if (!p_enabled) { - clearBlockImages(); - } - - getLayout()->setBlockImageEnabled(m_blockImageEnabled); -} - -void VPlainTextEdit::setImageWidthConstrainted(bool p_enabled) -{ - m_imageWidthConstrainted = p_enabled; - - updateImageWidth(); - - auto *layout = getLayout(); - emit layout->documentSizeChanged(layout->documentSize()); -} - -void VPlainTextEdit::updateImageWidth() -{ - bool needUpdate = false; - if (m_imageWidthConstrainted) { - int viewWidth = viewport()->size().width(); - m_maximumImageWidth = viewWidth - 10; - if (m_maximumImageWidth < 0) { - m_maximumImageWidth = viewWidth; - } - - needUpdate = true; - } else if (m_maximumImageWidth != INT_MAX) { - needUpdate = true; - m_maximumImageWidth = INT_MAX; - } - - if (needUpdate) { - m_imageMgr->updateImageWidth(m_maximumImageWidth); - } -} - -void VPlainTextEdit::resizeEvent(QResizeEvent *p_event) -{ - updateImageWidth(); - - QPlainTextEdit::resizeEvent(p_event); - - if (m_lineNumberType != LineNumberType::None) { - QRect rect = contentsRect(); - m_lineNumberArea->setGeometry(QRect(rect.left(), - rect.top(), - m_lineNumberArea->calculateWidth(), - rect.height())); - } -} - -void VPlainTextEdit::paintLineNumberArea(QPaintEvent *p_event) -{ - if (m_lineNumberType == LineNumberType::None) { - updateLineNumberAreaMargin(); - m_lineNumberArea->hide(); - return; - } - - QPainter painter(m_lineNumberArea); - painter.fillRect(p_event->rect(), m_lineNumberArea->getBackgroundColor()); - - QTextBlock block = firstVisibleBlock(); - if (!block.isValid()) { - return; - } - - int blockNumber = block.blockNumber(); - QRectF rect = blockBoundingGeometry(block); - int top = (int)(contentOffset().y() + rect.y()); - int bottom = top + (int)rect.height(); - int eventTop = p_event->rect().top(); - int eventBtm = p_event->rect().bottom(); - const int digitHeight = m_lineNumberArea->getDigitHeight(); - const int curBlockNumber = textCursor().block().blockNumber(); - painter.setPen(m_lineNumberArea->getForegroundColor()); - - // Display line number only in code block. - if (m_lineNumberType == LineNumberType::CodeBlock) { - int number = 0; - while (block.isValid() && top <= eventBtm) { - int blockState = block.userState(); - switch (blockState) { - case (int)BlockState::CodeBlockStart: - Q_ASSERT(number == 0); - number = 1; - break; - - case (int)BlockState::CodeBlockEnd: - number = 0; - break; - - case (int)BlockState::CodeBlock: - if (number == 0) { - // Need to find current line number in code block. - QTextBlock startBlock = block.previous(); - while (startBlock.isValid()) { - if (startBlock.userState() == (int)BlockState::CodeBlockStart) { - number = block.blockNumber() - startBlock.blockNumber(); - break; - } - - startBlock = startBlock.previous(); - } - } - - break; - - default: - break; - } - - if (blockState == (int)BlockState::CodeBlock) { - if (block.isVisible() && bottom >= eventTop) { - QString numberStr = QString::number(number); - painter.drawText(0, - top, - m_lineNumberArea->width(), - digitHeight, - Qt::AlignRight, - numberStr); - } - - ++number; - } - - block = block.next(); - top = bottom; - bottom = top + (int)blockBoundingRect(block).height(); - } - - return; - } - - // Handle m_lineNumberType 1 and 2. - Q_ASSERT(m_lineNumberType == LineNumberType::Absolute - || m_lineNumberType == LineNumberType::Relative); - while (block.isValid() && top <= eventBtm) { - if (block.isVisible() && bottom >= eventTop) { - bool currentLine = false; - int number = blockNumber + 1; - if (m_lineNumberType == LineNumberType::Relative) { - number = blockNumber - curBlockNumber; - if (number == 0) { - currentLine = true; - number = blockNumber + 1; - } else if (number < 0) { - number = -number; - } - } else if (blockNumber == curBlockNumber) { - currentLine = true; - } - - QString numberStr = QString::number(number); - - if (currentLine) { - QFont font = painter.font(); - font.setBold(true); - painter.setFont(font); - } - - painter.drawText(0, - top, - m_lineNumberArea->width(), - digitHeight, - Qt::AlignRight, - numberStr); - - if (currentLine) { - QFont font = painter.font(); - font.setBold(false); - painter.setFont(font); - } - } - - block = block.next(); - top = bottom; - bottom = top + (int)blockBoundingRect(block).height(); - ++blockNumber; - } - -} - -VPlainTextDocumentLayout *VPlainTextEdit::getLayout() const -{ - return qobject_cast(document()->documentLayout()); -} - -void VPlainTextEdit::updateLineNumberAreaMargin() -{ - int width = 0; - if (m_lineNumberType != LineNumberType::None) { - width = m_lineNumberArea->calculateWidth(); - } - - if (width != viewportMargins().left()) { - setViewportMargins(width, 0, 0, 0); - } -} - -void VPlainTextEdit::updateLineNumberArea() -{ - if (m_lineNumberType != LineNumberType::None) { - if (!m_lineNumberArea->isVisible()) { - updateLineNumberAreaMargin(); - m_lineNumberArea->show(); - } - - m_lineNumberArea->update(); - } else if (m_lineNumberArea->isVisible()) { - updateLineNumberAreaMargin(); - m_lineNumberArea->hide(); - } -} - -VPlainTextDocumentLayout::VPlainTextDocumentLayout(QTextDocument *p_document, - VImageResourceManager *p_imageMgr, - bool p_blockImageEnabled) - : QPlainTextDocumentLayout(p_document), - m_imageMgr(p_imageMgr), - m_blockImageEnabled(p_blockImageEnabled), - m_maximumImageWidth(INT_MAX) -{ -} - -QRectF VPlainTextDocumentLayout::blockBoundingRect(const QTextBlock &p_block) const -{ - QRectF br = QPlainTextDocumentLayout::blockBoundingRect(p_block); - if (!m_blockImageEnabled) { - return br; - } - - const VBlockImageInfo *info = m_imageMgr->findImageInfoByBlock(p_block.blockNumber()); - if (info) { - int tmp = info->m_margin + info->m_imageWidth; - if (tmp > m_maximumImageWidth) { - Q_ASSERT(info->m_imageWidth <= m_maximumImageWidth); - tmp = info->m_imageWidth; - } - - qreal width = (qreal)(tmp); - qreal dw = width > br.width() ? width - br.width() : 0; - qreal dh = (qreal)info->m_imageHeight; - - br.adjust(0, 0, dw, dh); - } - - return br; -} - -QRectF VPlainTextDocumentLayout::frameBoundingRect(QTextFrame *p_frame) const -{ - QRectF fr = QPlainTextDocumentLayout::frameBoundingRect(p_frame); - if (!m_blockImageEnabled) { - return fr; - } - - qreal imageWidth = (qreal)m_imageMgr->getMaximumImageWidth(); - qreal dw = imageWidth - fr.width(); - if (dw > 0) { - fr.adjust(0, 0, dw, 0); - } - - return fr; -} - -QSizeF VPlainTextDocumentLayout::documentSize() const -{ - QSizeF si = QPlainTextDocumentLayout::documentSize(); - if (!m_blockImageEnabled) { - return si; - } - - qreal imageWidth = (qreal)m_imageMgr->getMaximumImageWidth(); - if (imageWidth > si.width()) { - si.setWidth(imageWidth); - } - - return si; -} diff --git a/src/vplaintextedit.h b/src/vplaintextedit.h deleted file mode 100644 index 143784a3..00000000 --- a/src/vplaintextedit.h +++ /dev/null @@ -1,191 +0,0 @@ -#ifndef VPLAINTEXTEDIT_H -#define VPLAINTEXTEDIT_H - -#include -#include -#include - -#include "vlinenumberarea.h" - -class QTextDocument; -class VImageResourceManager; -class QPaintEvent; -class QPainter; -class QResizeEvent; -class VPlainTextDocumentLayout; - - -struct VBlockImageInfo -{ -public: - VBlockImageInfo() - : m_blockNumber(-1), m_margin(0), m_imageWidth(0), m_imageHeight(0) - { - } - - VBlockImageInfo(int p_blockNumber, - const QString &p_imageName, - int p_margin = 0) - : m_blockNumber(p_blockNumber), - m_imageName(p_imageName), - m_margin(p_margin), - m_imageWidth(0), - m_imageHeight(0) - { - } - - // Block number. - int m_blockNumber; - - // The name of the image corresponding to this block. - QString m_imageName; - - // Left margin of the image. - int m_margin; - -private: - // Width and height of the image display. - int m_imageWidth; - int m_imageHeight; - - friend class VImageResourceManager; - friend class VPlainTextEdit; - friend class VPlainTextDocumentLayout; -}; - - -class VPlainTextEdit : public QPlainTextEdit, public VTextEditWithLineNumber -{ - Q_OBJECT -public: - explicit VPlainTextEdit(QWidget *p_parent = nullptr); - - explicit VPlainTextEdit(const QString &p_text, QWidget *p_parent = nullptr); - - virtual ~VPlainTextEdit(); - - // Update images of these given blocks. - // Images of blocks not given here will be clear. - void updateBlockImages(const QVector &p_blocksInfo); - - void clearBlockImages(); - - // Whether the resoruce manager contains image of name @p_imageName. - bool containsImage(const QString &p_imageName) const; - - // Add an image to the resources. - void addImage(const QString &p_imageName, const QPixmap &p_image); - - void setBlockImageEnabled(bool p_enabled); - - void setImageWidthConstrainted(bool p_enabled); - - void paintLineNumberArea(QPaintEvent *p_event) Q_DECL_OVERRIDE; - - void setLineNumberType(LineNumberType p_type); - - void setLineNumberColor(const QColor &p_foreground, const QColor &p_background); - - // The minimum width of an image in pixels. - static const int c_minimumImageWidth; - -protected: - // Most logics are copied from QPlainTextEdit. - // Differences: draw images for blocks with preview image. - void paintEvent(QPaintEvent *p_event) Q_DECL_OVERRIDE; - - void resizeEvent(QResizeEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - // Update viewport margin to hold the line number area. - void updateLineNumberAreaMargin(); - - void updateLineNumberArea(); - -private: - void init(); - - // @p_blockRect: the content rect of @p_block. - void drawImageOfBlock(const QTextBlock &p_block, - QPainter *p_painter, - const QRectF &p_blockRect); - - QRectF originalBlockBoundingRect(const QTextBlock &p_block) const; - - VPlainTextDocumentLayout *getLayout() const; - - void updateImageWidth(); - - // Widget to display line number area. - VLineNumberArea *m_lineNumberArea; - - VImageResourceManager *m_imageMgr; - - bool m_blockImageEnabled; - - // Whether constraint the width of image to the width of the viewport. - bool m_imageWidthConstrainted; - - // Maximum width of the images. - int m_maximumImageWidth; - - LineNumberType m_lineNumberType; -}; - - -class VPlainTextDocumentLayout : public QPlainTextDocumentLayout -{ - Q_OBJECT -public: - explicit VPlainTextDocumentLayout(QTextDocument *p_document, - VImageResourceManager *p_imageMgr, - bool p_blockImageEnabled = false); - - // Will adjust the rect if there is an image for this block. - QRectF blockBoundingRect(const QTextBlock &p_block) const Q_DECL_OVERRIDE; - - QRectF frameBoundingRect(QTextFrame *p_frame) const Q_DECL_OVERRIDE; - - QSizeF documentSize() const Q_DECL_OVERRIDE; - - void setBlockImageEnabled(bool p_enabled); - - void setMaximumImageWidth(int p_width); - -private: - VImageResourceManager *m_imageMgr; - - bool m_blockImageEnabled; - - int m_maximumImageWidth; -}; - -inline void VPlainTextDocumentLayout::setBlockImageEnabled(bool p_enabled) -{ - m_blockImageEnabled = p_enabled; -} - -inline void VPlainTextDocumentLayout::setMaximumImageWidth(int p_width) -{ - m_maximumImageWidth = p_width; -} - -inline void VPlainTextEdit::setLineNumberType(LineNumberType p_type) -{ - if (p_type == m_lineNumberType) { - return; - } - - m_lineNumberType = p_type; - - updateLineNumberArea(); -} - -inline void VPlainTextEdit::setLineNumberColor(const QColor &p_foreground, - const QColor &p_background) -{ - m_lineNumberArea->setForegroundColor(p_foreground); - m_lineNumberArea->setBackgroundColor(p_background); -} - -#endif // VPLAINTEXTEDIT_H diff --git a/src/vpreviewmanager.cpp b/src/vpreviewmanager.cpp deleted file mode 100644 index d46e25d7..00000000 --- a/src/vpreviewmanager.cpp +++ /dev/null @@ -1,388 +0,0 @@ -#include "vpreviewmanager.h" - -#include -#include -#include -#include -#include -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "vdownloader.h" -#include "hgmarkdownhighlighter.h" - -extern VConfigManager *g_config; - -VPreviewManager::VPreviewManager(VMdEditor *p_editor, HGMarkdownHighlighter *p_highlighter) - : QObject(p_editor), - m_editor(p_editor), - m_document(p_editor->document()), - m_highlighter(p_highlighter), - m_previewEnabled(false), - m_timeStamp(0) -{ - m_downloader = new VDownloader(this); - connect(m_downloader, &VDownloader::downloadFinished, - this, &VPreviewManager::imageDownloaded); -} - -void VPreviewManager::imageLinksUpdated(const QVector &p_imageRegions) -{ - if (!m_previewEnabled) { - return; - } - - TS ts = ++m_timeStamp; - m_imageRegions = p_imageRegions; - - previewImages(ts); -} - -void VPreviewManager::imageDownloaded(const QByteArray &p_data, const QString &p_url) -{ - if (!m_previewEnabled) { - return; - } - - auto it = m_urlToName.find(p_url); - if (it == m_urlToName.end()) { - return; - } - - QString name = it.value(); - m_urlToName.erase(it); - - if (m_editor->containsImage(name) || name.isEmpty()) { - return; - } - - QPixmap image; - image.loadFromData(p_data); - - if (!image.isNull()) { - m_editor->addImage(name, image); - qDebug() << "downloaded image inserted in resource manager" << p_url << name; - emit requestUpdateImageLinks(); - } -} - -void VPreviewManager::setPreviewEnabled(bool p_enabled) -{ - if (m_previewEnabled != p_enabled) { - m_previewEnabled = p_enabled; - - if (!m_previewEnabled) { - clearPreview(); - } else { - requestUpdateImageLinks(); - } - } -} - -void VPreviewManager::clearPreview() -{ - m_imageRegions.clear(); - - long long ts = ++m_timeStamp; - - for (int i = 0; i < (int)PreviewSource::MaxNumberOfSources; ++i) { - clearBlockObsoletePreviewInfo(ts, static_cast(i)); - - clearObsoleteImages(ts, static_cast(i)); - } -} - -void VPreviewManager::previewImages(TS p_timeStamp) -{ - QVector imageLinks; - fetchImageLinksFromRegions(imageLinks); - - updateBlockPreviewInfo(p_timeStamp, imageLinks); - - clearBlockObsoletePreviewInfo(p_timeStamp, PreviewSource::ImageLink); - - clearObsoleteImages(p_timeStamp, PreviewSource::ImageLink); -} - -// Returns true if p_text[p_start, p_end) is all spaces. -static bool isAllSpaces(const QString &p_text, int p_start, int p_end) -{ - int len = qMin(p_text.size(), p_end); - for (int i = p_start; i < len; ++i) { - if (!p_text[i].isSpace()) { - return false; - } - } - - return true; -} - -void VPreviewManager::fetchImageLinksFromRegions(QVector &p_imageLinks) -{ - p_imageLinks.clear(); - - if (m_imageRegions.isEmpty()) { - return; - } - - p_imageLinks.reserve(m_imageRegions.size()); - - QTextDocument *doc = m_editor->document(); - - for (int i = 0; i < m_imageRegions.size(); ++i) { - VElementRegion ® = m_imageRegions[i]; - QTextBlock block = doc->findBlock(reg.m_startPos); - if (!block.isValid()) { - continue; - } - - int blockStart = block.position(); - int blockEnd = blockStart + block.length() - 1; - QString text = block.text(); - Q_ASSERT(reg.m_endPos <= blockEnd); - ImageLinkInfo info(reg.m_startPos, - reg.m_endPos, - blockStart, - block.blockNumber(), - calculateBlockMargin(block)); - if ((reg.m_startPos == blockStart - || isAllSpaces(text, 0, reg.m_startPos - blockStart)) - && (reg.m_endPos == blockEnd - || isAllSpaces(text, reg.m_endPos - blockStart, blockEnd - blockStart))) { - // Image block. - info.m_isBlock = true; - info.m_linkUrl = fetchImagePathToPreview(text, info.m_linkShortUrl); - } else { - // Inline image. - info.m_isBlock = false; - info.m_linkUrl = fetchImagePathToPreview(text.mid(reg.m_startPos - blockStart, - reg.m_endPos - reg.m_startPos), - info.m_linkShortUrl); - } - - if (info.m_linkUrl.isEmpty()) { - continue; - } - - p_imageLinks.append(info); - - qDebug() << "image region" << i - << info.m_startPos << info.m_endPos << info.m_blockNumber - << info.m_linkShortUrl << info.m_linkUrl << info.m_isBlock; - } -} - -QString VPreviewManager::fetchImageUrlToPreview(const QString &p_text) -{ - QRegExp regExp(VUtils::c_imageLinkRegExp); - - int index = regExp.indexIn(p_text); - if (index == -1) { - return QString(); - } - - int lastIndex = regExp.lastIndexIn(p_text); - if (lastIndex != index) { - return QString(); - } - - return regExp.capturedTexts()[2].trimmed(); -} - -QString VPreviewManager::fetchImagePathToPreview(const QString &p_text, QString &p_url) -{ - p_url = fetchImageUrlToPreview(p_text); - if (p_url.isEmpty()) { - return p_url; - } - - const VFile *file = m_editor->getFile(); - - QString imagePath; - QFileInfo info(file->fetchBasePath(), p_url); - - if (info.exists()) { - if (info.isNativePath()) { - // Local file. - imagePath = QDir::cleanPath(info.absoluteFilePath()); - } else { - imagePath = p_url; - } - } else { - QString decodedUrl(p_url); - VUtils::decodeUrl(decodedUrl); - QFileInfo dinfo(file->fetchBasePath(), decodedUrl); - if (dinfo.exists()) { - if (dinfo.isNativePath()) { - // Local file. - imagePath = QDir::cleanPath(dinfo.absoluteFilePath()); - } else { - imagePath = p_url; - } - } else { - QUrl url(p_url); - imagePath = url.toString(); - } - } - - return imagePath; -} - -QString VPreviewManager::imageResourceName(const ImageLinkInfo &p_link) -{ - QString name = p_link.m_linkShortUrl; - if (m_editor->containsImage(name) - || name.isEmpty()) { - return name; - } - - // Add it to the resource. - QString imgPath = p_link.m_linkUrl; - QFileInfo info(imgPath); - QPixmap image; - if (info.exists()) { - // Local file. - image = QPixmap(imgPath); - } else { - // URL. Try to download it. - m_downloader->download(imgPath); - m_urlToName.insert(imgPath, name); - } - - if (image.isNull()) { - return QString(); - } - - m_editor->addImage(name, image); - return name; -} - -int VPreviewManager::calculateBlockMargin(const QTextBlock &p_block) -{ - static QHash spaceWidthOfFonts; - - if (!p_block.isValid()) { - return 0; - } - - QString text = p_block.text(); - int nrSpaces = 0; - for (int i = 0; i < text.size(); ++i) { - if (!text[i].isSpace()) { - break; - } else if (text[i] == ' ') { - ++nrSpaces; - } else if (text[i] == '\t') { - nrSpaces += m_editor->tabStopWidth(); - } - } - - if (nrSpaces == 0) { - return 0; - } - - int spaceWidth = 0; - QFont font = p_block.charFormat().font(); - QString fontName = font.toString(); - auto it = spaceWidthOfFonts.find(fontName); - if (it != spaceWidthOfFonts.end()) { - spaceWidth = it.value(); - } else { - spaceWidth = QFontMetrics(font).width(' '); - spaceWidthOfFonts.insert(fontName, spaceWidth); - } - - return spaceWidth * nrSpaces; -} - -void VPreviewManager::updateBlockPreviewInfo(TS p_timeStamp, - const QVector &p_imageLinks) -{ - for (auto const & link : p_imageLinks) { - QTextBlock block = m_document->findBlockByNumber(link.m_blockNumber); - if (!block.isValid()) { - continue; - } - - QString name = imageResourceName(link); - if (name.isEmpty()) { - continue; - } - - VTextBlockData *blockData = dynamic_cast(block.userData()); - Q_ASSERT(blockData); - - VPreviewInfo *info = new VPreviewInfo(PreviewSource::ImageLink, - p_timeStamp, - link.m_startPos - link.m_blockPos, - link.m_endPos - link.m_blockPos, - link.m_padding, - !link.m_isBlock, - name, - m_editor->imageSize(name)); - blockData->insertPreviewInfo(info); - - imageCache(PreviewSource::ImageLink).insert(name, p_timeStamp); - - qDebug() << "block" << link.m_blockNumber - << imageCache(PreviewSource::ImageLink).size() - << blockData->toString(); - } -} - -void VPreviewManager::clearObsoleteImages(long long p_timeStamp, PreviewSource p_source) -{ - auto cache = imageCache(p_source); - - for (auto it = cache.begin(); it != cache.end();) { - if (it.value() < p_timeStamp) { - m_editor->removeImage(it.key()); - it = cache.erase(it); - } else { - ++it; - } - } -} - -void VPreviewManager::clearBlockObsoletePreviewInfo(long long p_timeStamp, - PreviewSource p_source) -{ - QSet affectedBlocks; - QVector obsoleteBlocks; - auto blocks = m_highlighter->getPossiblePreviewBlocks(); - qDebug() << "possible preview blocks" << blocks; - for (auto i : blocks) { - QTextBlock block = m_document->findBlockByNumber(i); - if (!block.isValid()) { - obsoleteBlocks.append(i); - continue; - } - - VTextBlockData *blockData = dynamic_cast(block.userData()); - if (!blockData) { - continue; - } - - if (blockData->clearObsoletePreview(p_timeStamp, p_source)) { - affectedBlocks.insert(i); - } - - if (blockData->getPreviews().isEmpty()) { - obsoleteBlocks.append(i); - } - } - - m_highlighter->clearPossiblePreviewBlocks(obsoleteBlocks); - - m_editor->relayout(affectedBlocks); -} - -void VPreviewManager::refreshPreview() -{ - if (!m_previewEnabled) { - return; - } - - clearPreview(); - - requestUpdateImageLinks(); -} diff --git a/src/vpreviewmanager.h b/src/vpreviewmanager.h deleted file mode 100644 index 6fb47066..00000000 --- a/src/vpreviewmanager.h +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef VPREVIEWMANAGER_H -#define VPREVIEWMANAGER_H - -#include -#include -#include -#include -#include -#include "hgmarkdownhighlighter.h" -#include "vmdeditor.h" -#include "vtextblockdata.h" - -class VDownloader; - -typedef long long TS; - - -class VPreviewManager : public QObject -{ - Q_OBJECT -public: - VPreviewManager(VMdEditor *p_editor, HGMarkdownHighlighter *p_highlighter); - - void setPreviewEnabled(bool p_enabled); - - // Clear all the preview. - void clearPreview(); - - // Refresh all the preview. - void refreshPreview(); - -public slots: - // Image links were updated from the highlighter. - void imageLinksUpdated(const QVector &p_imageRegions); - -signals: - // Request highlighter to update image links. - void requestUpdateImageLinks(); - -private slots: - // Non-local image downloaded for preview. - void imageDownloaded(const QByteArray &p_data, const QString &p_url); - -private: - struct ImageLinkInfo - { - ImageLinkInfo() - : m_startPos(-1), - m_endPos(-1), - m_blockPos(-1), - m_blockNumber(-1), - m_padding(0), - m_isBlock(false) - { - } - - ImageLinkInfo(int p_startPos, - int p_endPos, - int p_blockPos, - int p_blockNumber, - int p_padding) - : m_startPos(p_startPos), - m_endPos(p_endPos), - m_blockPos(p_blockPos), - m_blockNumber(p_blockNumber), - m_padding(p_padding), - m_isBlock(false) - { - } - - int m_startPos; - - int m_endPos; - - // Position of this block. - int m_blockPos; - - int m_blockNumber; - - // Left padding of this block in pixels. - int m_padding; - - // Short URL within the () of ![](). - // Used as the ID of the image. - QString m_linkShortUrl; - - // Full URL of the link. - QString m_linkUrl; - - // Whether it is an image block. - bool m_isBlock; - }; - - // Start to preview images according to image links. - void previewImages(TS p_timeStamp); - - // According to m_imageRegions, fetch the image link Url. - // @p_imageRegions: output. - void fetchImageLinksFromRegions(QVector &p_imageLinks); - - // Fetch the image link's URL if there is only one link. - QString fetchImageUrlToPreview(const QString &p_text); - - // Fetch teh image's full path if there is only one image link. - // @p_url: contains the short URL in ![](). - QString fetchImagePathToPreview(const QString &p_text, QString &p_url); - - // Update the preview info of related blocks according to @p_imageLinks. - void updateBlockPreviewInfo(TS p_timeStamp, const QVector &p_imageLinks); - - // Get the name of the image in the resource manager. - // Will add the image to the resource manager if not exists. - // Returns empty if fail to add the image to the resource manager. - QString imageResourceName(const ImageLinkInfo &p_link); - - // Calculate the block margin (prefix spaces) in pixels. - int calculateBlockMargin(const QTextBlock &p_block); - - QHash &imageCache(PreviewSource p_source); - - void clearObsoleteImages(long long p_timeStamp, PreviewSource p_source); - - void clearBlockObsoletePreviewInfo(long long p_timeStamp, PreviewSource p_source); - - VMdEditor *m_editor; - - QTextDocument *m_document; - - HGMarkdownHighlighter *m_highlighter; - - VDownloader *m_downloader; - - // Whether preview is enabled. - bool m_previewEnabled; - - // Regions of all the image links. - QVector m_imageRegions; - - // Map from URL to name in the resource manager. - // Used for downloading images. - QHash m_urlToName; - - TS m_timeStamp; - - // Used to discard obsolete images. One per each preview source. - QHash m_imageCaches[(int)PreviewSource::MaxNumberOfSources]; -}; - -inline QHash &VPreviewManager::imageCache(PreviewSource p_source) -{ - return m_imageCaches[(int)p_source]; -} -#endif // VPREVIEWMANAGER_H diff --git a/src/vpreviewpage.cpp b/src/vpreviewpage.cpp deleted file mode 100644 index d87859d7..00000000 --- a/src/vpreviewpage.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "vpreviewpage.h" - -#include - -#include "vmainwindow.h" - -extern VMainWindow *g_mainWin; - -VPreviewPage::VPreviewPage(QWidget *parent) : QWebEnginePage(parent) -{ - -} - -bool VPreviewPage::acceptNavigationRequest(const QUrl &p_url, - QWebEnginePage::NavigationType p_type, - bool p_isMainFrame) -{ - Q_UNUSED(p_type); - Q_UNUSED(p_isMainFrame); - - if (p_url.isLocalFile()) { - QString filePath = p_url.toLocalFile(); - if (g_mainWin->tryOpenInternalFile(filePath)) { - qDebug() << "internal notes jump" << filePath; - return false; - } - } - - QDesktopServices::openUrl(p_url); - return false; -} diff --git a/src/vpreviewpage.h b/src/vpreviewpage.h deleted file mode 100644 index eca8a25c..00000000 --- a/src/vpreviewpage.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef VPREVIEWPAGE_H -#define VPREVIEWPAGE_H - -#include - -class VPreviewPage : public QWebEnginePage -{ - Q_OBJECT -public: - explicit VPreviewPage(QWidget *parent = 0); - -protected: - bool acceptNavigationRequest(const QUrl &p_url, - NavigationType p_type, - bool p_isMainFrame); -}; - -#endif // VPREVIEWPAGE_H diff --git a/src/vsingleinstanceguard.cpp b/src/vsingleinstanceguard.cpp deleted file mode 100644 index 42437190..00000000 --- a/src/vsingleinstanceguard.cpp +++ /dev/null @@ -1,167 +0,0 @@ -#include "vsingleinstanceguard.h" -#include - -#include "utils/vutils.h" - -const QString VSingleInstanceGuard::c_memKey = "vnote_shared_memory"; -const int VSingleInstanceGuard::c_magic = 133191933; - -VSingleInstanceGuard::VSingleInstanceGuard() - : m_sharedMemory(c_memKey) -{ -} - -bool VSingleInstanceGuard::tryRun() -{ - // If we can attach to the sharedmemory, there is another instance running. - // In Linux, crashes may cause the shared memory segment remains. In this case, - // this will attach to the old segment, then exit, freeing the old segment. - if (m_sharedMemory.attach()) { - qDebug() << "another instance is running"; - return false; - } - - // Try to create it. - bool ret = m_sharedMemory.create(sizeof(SharedStruct)); - if (ret) { - // We created it. - m_sharedMemory.lock(); - SharedStruct *str = (SharedStruct *)m_sharedMemory.data(); - str->m_magic = c_magic; - str->m_filesBufIdx = 0; - str->m_askedToShow = false; - m_sharedMemory.unlock(); - return true; - } else { - qDebug() << "fail to create shared memory segment"; - return false; - } -} - -void VSingleInstanceGuard::openExternalFiles(const QStringList &p_files) -{ - if (p_files.isEmpty()) { - return; - } - - if (!m_sharedMemory.isAttached()) { - if (!m_sharedMemory.attach()) { - qDebug() << "fail to attach to the shared memory segment" - << (m_sharedMemory.error() ? m_sharedMemory.errorString() : ""); - return; - } - } - - qDebug() << "try to request another instance to open files" << p_files; - - int idx = 0; - int tryCount = 100; - while (tryCount--) { - qDebug() << "set shared memory one round" << idx << "of" << p_files.size(); - m_sharedMemory.lock(); - SharedStruct *str = (SharedStruct *)m_sharedMemory.data(); - V_ASSERT(str->m_magic == c_magic); - for (; idx < p_files.size(); ++idx) { - if (p_files[idx].size() + 1 > FilesBufCount) { - qDebug() << "skip file since its long name" << p_files[idx]; - // Skip this long long name file. - continue; - } - - if (!appendFileToBuffer(str, p_files[idx])) { - break; - } - } - - m_sharedMemory.unlock(); - - if (idx < p_files.size()) { - VUtils::sleepWait(500); - } else { - break; - } - } -} - -bool VSingleInstanceGuard::appendFileToBuffer(SharedStruct *p_str, const QString &p_file) -{ - if (p_file.isEmpty()) { - return true; - } - - int strSize = p_file.size(); - if (strSize + 1 > FilesBufCount - p_str->m_filesBufIdx) { - qDebug() << "no enough space for" << p_file; - return false; - } - - // Put the size first. - p_str->m_filesBuf[p_str->m_filesBufIdx++] = (ushort)strSize; - const QChar *data = p_file.constData(); - for (int i = 0; i < strSize; ++i) { - p_str->m_filesBuf[p_str->m_filesBufIdx++] = data[i].unicode(); - } - - qDebug() << "after appended one file" << p_str->m_filesBufIdx << p_file; - return true; -} - -QStringList VSingleInstanceGuard::fetchFilesToOpen() -{ - QStringList files; - Q_ASSERT(m_sharedMemory.isAttached()); - m_sharedMemory.lock(); - SharedStruct *str = (SharedStruct *)m_sharedMemory.data(); - Q_ASSERT(str->m_magic == c_magic); - Q_ASSERT(str->m_filesBufIdx <= FilesBufCount); - int idx = 0; - while (idx < str->m_filesBufIdx) { - int strSize = str->m_filesBuf[idx++]; - Q_ASSERT(strSize <= str->m_filesBufIdx - idx); - QString file; - for (int i = 0; i < strSize; ++i) { - file.append(QChar(str->m_filesBuf[idx++])); - } - - files.append(file); - } - - str->m_filesBufIdx = 0; - m_sharedMemory.unlock(); - - return files; -} - -void VSingleInstanceGuard::showInstance() -{ - if (!m_sharedMemory.isAttached()) { - if (!m_sharedMemory.attach()) { - qDebug() << "fail to attach to the shared memory segment" - << (m_sharedMemory.error() ? m_sharedMemory.errorString() : ""); - return; - } - } - - m_sharedMemory.lock(); - SharedStruct *str = (SharedStruct *)m_sharedMemory.data(); - V_ASSERT(str->m_magic == c_magic); - str->m_askedToShow = true; - m_sharedMemory.unlock(); - - qDebug() << "try to request another instance to show up"; -} - -bool VSingleInstanceGuard::fetchAskedToShow() -{ - bool ret = false; - - Q_ASSERT(m_sharedMemory.isAttached()); - m_sharedMemory.lock(); - SharedStruct *str = (SharedStruct *)m_sharedMemory.data(); - Q_ASSERT(str->m_magic == c_magic); - ret = str->m_askedToShow; - str->m_askedToShow = false; - m_sharedMemory.unlock(); - - return ret; -} diff --git a/src/vsingleinstanceguard.h b/src/vsingleinstanceguard.h deleted file mode 100644 index 750f3a3a..00000000 --- a/src/vsingleinstanceguard.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef VSINGLEINSTANCEGUARD_H -#define VSINGLEINSTANCEGUARD_H - -#include -#include -#include - -class VSingleInstanceGuard -{ -public: - VSingleInstanceGuard(); - - // Return ture if this is the only instance of VNote. - bool tryRun(); - - // There is already another instance running. - // Call this to ask that instance to open external files passed in - // via command line arguments. - void openExternalFiles(const QStringList &p_files); - - // Ask another instance to show itself. - void showInstance(); - - // Fetch files from shared memory to open. - // Will clear the shared memory. - QStringList fetchFilesToOpen(); - - // Whether this instance is asked to show itself. - bool fetchAskedToShow(); - -private: - // The count of the entries in the buffer to hold the path of the files to open. - enum { FilesBufCount = 1024 }; - - struct SharedStruct { - // A magic number to identify if this struct is initialized - int m_magic; - - // Next empty entry in m_filesBuf. - int m_filesBufIdx; - - // File paths to be opened. - // Encoded in this way with 2 bytes for each size part. - // [size of file1][file1][size of file2][file 2] - // Unicode representation of QString. - ushort m_filesBuf[FilesBufCount]; - - // Whether other instances ask to show the legal instance. - bool m_askedToShow; - }; - - // Append @p_file to the shared struct files buffer. - // Returns true if succeeds or false if there is no enough space. - bool appendFileToBuffer(SharedStruct *p_str, const QString &p_file); - - QSharedMemory m_sharedMemory; - - static const QString c_memKey; - static const int c_magic; -}; - -#endif // VSINGLEINSTANCEGUARD_H diff --git a/src/vsnippet.cpp b/src/vsnippet.cpp deleted file mode 100644 index 17e0676f..00000000 --- a/src/vsnippet.cpp +++ /dev/null @@ -1,253 +0,0 @@ -#include "vsnippet.h" - -#include -#include - -#include "vconstants.h" -#include "utils/vutils.h" -#include "utils/veditutils.h" -#include "utils/vmetawordmanager.h" - -extern VMetaWordManager *g_mwMgr; - -const QString VSnippet::c_defaultCursorMark = "@@"; - -const QString VSnippet::c_defaultSelectionMark = "$$"; - -QVector VSnippet::s_allShortcuts; - -VSnippet::VSnippet() - : m_type(Type::PlainText), - m_cursorMark(c_defaultCursorMark), - m_autoIndent(false) -{ -} - -VSnippet::VSnippet(const QString &p_name, - Type p_type, - const QString &p_content, - const QString &p_cursorMark, - const QString &p_selectionMark, - QChar p_shortcut, - bool p_autoIndent) - : m_name(p_name), - m_type(p_type), - m_content(p_content), - m_cursorMark(p_cursorMark), - m_selectionMark(p_selectionMark), - m_shortcut(p_shortcut), - m_autoIndent(p_autoIndent) -{ - Q_ASSERT(m_selectionMark != m_cursorMark); -} - -bool VSnippet::update(const QString &p_name, - Type p_type, - const QString &p_content, - const QString &p_cursorMark, - const QString &p_selectionMark, - QChar p_shortcut, - bool p_autoIndent) -{ - bool updated = false; - if (m_name != p_name) { - m_name = p_name; - updated = true; - } - - if (m_type != p_type) { - m_type = p_type; - updated = true; - } - - if (m_content != p_content) { - m_content = p_content; - updated = true; - } - - if (m_cursorMark != p_cursorMark) { - m_cursorMark = p_cursorMark; - updated = true; - } - - if (m_selectionMark != p_selectionMark) { - m_selectionMark = p_selectionMark; - updated = true; - } - - if (m_shortcut != p_shortcut) { - m_shortcut = p_shortcut; - updated = true; - } - - if (m_autoIndent != p_autoIndent) { - m_autoIndent = p_autoIndent; - updated = true; - } - - qDebug() << "snippet" << m_name << "updated" << updated; - - return updated; -} - -QString VSnippet::typeStr(VSnippet::Type p_type) -{ - switch (p_type) { - case Type::PlainText: - return QObject::tr("PlainText"); - - case Type::Html: - return QObject::tr("Html"); - - default: - return QObject::tr("Invalid"); - } -} - -QJsonObject VSnippet::toJson() const -{ - QJsonObject snip; - snip[SnippetConfig::c_name] = m_name; - snip[SnippetConfig::c_type] = (int)m_type; - snip[SnippetConfig::c_cursorMark] = m_cursorMark; - snip[SnippetConfig::c_selectionMark] = m_selectionMark; - snip[SnippetConfig::c_shortcut] = m_shortcut.isNull() ? "" : QString(m_shortcut); - snip[SnippetConfig::c_autoIndent] = m_autoIndent; - - return snip; -} - -VSnippet VSnippet::fromJson(const QJsonObject &p_json) -{ - QChar shortcut; - QString shortcutStr = p_json[SnippetConfig::c_shortcut].toString(); - if (!shortcutStr.isEmpty() && isValidShortcut(shortcutStr[0])) { - shortcut = shortcutStr[0]; - } - - VSnippet snip(p_json[SnippetConfig::c_name].toString(), - static_cast(p_json[SnippetConfig::c_type].toInt()), - "", - p_json[SnippetConfig::c_cursorMark].toString(), - p_json[SnippetConfig::c_selectionMark].toString(), - shortcut, - p_json[SnippetConfig::c_autoIndent].toBool()); - - return snip; -} - -const QVector &VSnippet::getAllShortcuts() -{ - if (s_allShortcuts.isEmpty()) { - // Init. - char ch = 'a'; - while (true) { - s_allShortcuts.append(ch); - if (ch == 'z') { - break; - } - - ch++; - } - } - - return s_allShortcuts; -} - -bool VSnippet::isValidShortcut(QChar p_char) -{ - if (p_char >= 'a' && p_char <= 'z') { - return true; - } - - return false; -} - -bool VSnippet::apply(QTextCursor &p_cursor) const -{ - p_cursor.beginEditBlock(); - // Delete selected text. - QString selection = VEditUtils::selectedText(p_cursor); - p_cursor.removeSelectedText(); - - // Evaluate the content. - QString content = g_mwMgr->evaluate(m_content); - - if (content.isEmpty()) { - p_cursor.endEditBlock(); - return true; - } - - // Find the cursor mark and break the content. - QString secondPart; - if (!m_cursorMark.isEmpty()) { - QStringList parts = content.split(m_cursorMark); - Q_ASSERT(parts.size() < 3 && parts.size() > 0); - - content = parts[0]; - if (parts.size() == 2) { - secondPart = parts[1]; - } - } - - // Replace the selection mark. - // Content may be empty. - if (!m_selectionMark.isEmpty() && !content.isEmpty()) { - content.replace(m_selectionMark, selection); - } - - int pos = p_cursor.position() + content.size(); - - if (!m_selectionMark.isEmpty() && !secondPart.isEmpty()) { - secondPart.replace(m_selectionMark, selection); - } - - content += secondPart; - - // Auto indent. - QTextBlock startBlock = p_cursor.block(); - QTextBlock endBlock; - QString indentation = VEditUtils::fetchIndentSpaces(startBlock); - - // Insert it. - switch (m_type) { - case Type::Html: - p_cursor.insertHtml(content); - break; - - case Type::PlainText: - V_FALLTHROUGH; - - default: - p_cursor.insertText(content); - break; - } - - endBlock = p_cursor.block(); - - if (m_autoIndent - && startBlock != endBlock - && !indentation.isEmpty()) { - // Indent (startBlock, endBlock]. - startBlock = startBlock.next(); - while (startBlock.isValid()) { - int tmpPos = startBlock.position(); - p_cursor.setPosition(tmpPos); - VEditUtils::indentBlock(p_cursor, indentation, false); - if (tmpPos <= pos) { - pos += indentation.size(); - } - - if (startBlock == endBlock) { - break; - } - - startBlock = startBlock.next(); - } - } - - p_cursor.setPosition(pos); - - p_cursor.endEditBlock(); - return true; -} diff --git a/src/vsnippet.h b/src/vsnippet.h deleted file mode 100644 index 084389df..00000000 --- a/src/vsnippet.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef VSNIPPET_H -#define VSNIPPET_H - -#include -#include -#include - - -class VSnippet -{ -public: - enum Type - { - PlainText = 0, - Html, - Invalid - }; - - VSnippet(); - - VSnippet(const QString &p_name, - Type p_type = Type::PlainText, - const QString &p_content = QString(), - const QString &p_cursorMark = c_defaultCursorMark, - const QString &p_selectionMark = c_defaultSelectionMark, - QChar p_shortcut = QChar(), - bool p_autoIndent = false); - - // Return true if there is any update. - bool update(const QString &p_name, - Type p_type, - const QString &p_content, - const QString &p_cursorMark, - const QString &p_selectionMark, - QChar p_shortcut, - bool p_autoIndent); - - const QString &getName() const - { - return m_name; - } - - VSnippet::Type getType() const - { - return m_type; - } - - const QString &getCursorMark() const - { - return m_cursorMark; - } - - const QString &getSelectionMark() const - { - return m_selectionMark; - } - - const QString &getContent() const - { - return m_content; - } - - QChar getShortcut() const - { - return m_shortcut; - } - - bool getAutoIndent() const - { - return m_autoIndent; - } - - void setContent(const QString &p_content) - { - m_content = p_content; - } - - // Not including m_content. - QJsonObject toJson() const; - - // Apply this snippet via @p_cursor. - bool apply(QTextCursor &p_cursor) const; - - // Not including m_content. - static VSnippet fromJson(const QJsonObject &p_json); - - static QString typeStr(VSnippet::Type p_type); - - static const QVector &getAllShortcuts(); - - static bool isValidShortcut(QChar p_char); - -private: - // File name in the snippet folder. - QString m_name; - - Type m_type; - - // Support magic word. - QString m_content; - - // String in the content that mark the position of the cursor after insertion. - // If there is no such mark in the content, the cursor should be put at the - // end of the insertion. - QString m_cursorMark; - - // Selection marks in the content will be replaced by selected text. - QString m_selectionMark; - - // Shortcut to apply this snippet. - QChar m_shortcut; - - // Auto indent with the first line. - bool m_autoIndent; - - static const QString c_defaultCursorMark; - - static const QString c_defaultSelectionMark; - - static QVector s_allShortcuts; -}; - -#endif // VSNIPPET_H diff --git a/src/vsnippetlist.cpp b/src/vsnippetlist.cpp deleted file mode 100644 index 3e4c9f9d..00000000 --- a/src/vsnippetlist.cpp +++ /dev/null @@ -1,626 +0,0 @@ -#include "vsnippetlist.h" - -#include - -#include "vconfigmanager.h" -#include "dialog/veditsnippetdialog.h" -#include "utils/vutils.h" -#include "utils/vimnavigationforwidget.h" -#include "dialog/vsortdialog.h" -#include "dialog/vconfirmdeletiondialog.h" -#include "vmainwindow.h" -#include "utils/viconutils.h" - -extern VConfigManager *g_config; - -extern VMainWindow *g_mainWin; - -const QString VSnippetList::c_infoShortcutSequence = "F2"; - -VSnippetList::VSnippetList(QWidget *p_parent) - : QWidget(p_parent) -{ - setupUI(); - - initShortcuts(); - - initActions(); - - if (!readSnippetsFromConfig()) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to read snippets from %2.") - .arg(g_config->c_dataTextStyle) - .arg(g_config->getSnippetConfigFolder()), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - updateContent(); -} - -void VSnippetList::setupUI() -{ - m_addBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/add_snippet.svg"), ""); - m_addBtn->setToolTip(tr("New Snippet")); - m_addBtn->setProperty("FlatBtn", true); - connect(m_addBtn, &QPushButton::clicked, - this, &VSnippetList::newSnippet); - - m_locateBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/locate_snippet.svg"), ""); - m_locateBtn->setToolTip(tr("Open Folder")); - m_locateBtn->setProperty("FlatBtn", true); - connect(m_locateBtn, &QPushButton::clicked, - this, [this]() { - makeSureFolderExist(); - QUrl url = QUrl::fromLocalFile(g_config->getSnippetConfigFolder()); - QDesktopServices::openUrl(url); - }); - - m_numLabel = new QLabel(); - - QHBoxLayout *btnLayout = new QHBoxLayout; - btnLayout->addWidget(m_addBtn); - btnLayout->addWidget(m_locateBtn); - btnLayout->addStretch(); - btnLayout->addWidget(m_numLabel); - btnLayout->setContentsMargins(0, 0, 3, 0); - - m_snippetList = new QListWidget(); - m_snippetList->setAttribute(Qt::WA_MacShowFocusRect, false); - m_snippetList->setContextMenuPolicy(Qt::CustomContextMenu); - m_snippetList->setSelectionMode(QAbstractItemView::ExtendedSelection); - m_snippetList->setEditTriggers(QAbstractItemView::SelectedClicked); - connect(m_snippetList, &QListWidget::customContextMenuRequested, - this, &VSnippetList::handleContextMenuRequested); - connect(m_snippetList, &QListWidget::itemActivated, - this, &VSnippetList::handleItemActivated); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(btnLayout); - mainLayout->addWidget(m_snippetList); - mainLayout->setContentsMargins(0, 0, 0, 0); - - setLayout(mainLayout); -} - -void VSnippetList::initActions() -{ - m_applyAct = new QAction(VIconUtils::menuIcon(":/resources/icons/apply_snippet.svg"), - tr("&Apply"), - this); - m_applyAct->setToolTip(tr("Insert this snippet in editor")); - connect(m_applyAct, &QAction::triggered, - this, [this]() { - QListWidgetItem *item = m_snippetList->currentItem(); - handleItemActivated(item); - }); - - m_infoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/snippet_info.svg"), - tr("&Info\t%1").arg(VUtils::getShortcutText(c_infoShortcutSequence)), - this); - m_infoAct->setToolTip(tr("View and edit snippet's information")); - connect(m_infoAct, &QAction::triggered, - this, &VSnippetList::snippetInfo); - - m_deleteAct = new QAction(VIconUtils::menuDangerIcon(":/resources/icons/delete_snippet.svg"), - tr("&Delete"), - this); - m_deleteAct->setToolTip(tr("Delete selected snippets")); - connect(m_deleteAct, &QAction::triggered, - this, &VSnippetList::deleteSelectedItems); - - m_sortAct = new QAction(VIconUtils::menuIcon(":/resources/icons/sort.svg"), - tr("&Sort"), - this); - m_sortAct->setToolTip(tr("Sort snippets manually")); - connect(m_sortAct, &QAction::triggered, - this, &VSnippetList::sortItems); -} - -void VSnippetList::initShortcuts() -{ - QShortcut *infoShortcut = new QShortcut(QKeySequence(c_infoShortcutSequence), this); - infoShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(infoShortcut, &QShortcut::activated, - this, &VSnippetList::snippetInfo); -} - -void VSnippetList::newSnippet() -{ - QString defaultName = VUtils::getFileNameWithSequence(g_config->getSnippetConfigFolder(), - "snippet"); - - VSnippet tmpSnippet(defaultName); - QString info = tr("Magic words are supported in the content of the snippet."); - VEditSnippetDialog dialog(tr("Create Snippet"), - info, - m_snippets, - tmpSnippet, - this); - if (dialog.exec() == QDialog::Accepted) { - makeSureFolderExist(); - VSnippet snippet(dialog.getNameInput(), - dialog.getTypeInput(), - dialog.getContentInput(), - dialog.getCursorMarkInput(), - dialog.getSelectionMarkInput(), - dialog.getShortcutInput(), - dialog.getAutoIndentInput()); - - QString errMsg; - if (!addSnippet(snippet, &errMsg)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to create snippet %2.") - .arg(g_config->c_dataTextStyle) - .arg(snippet.getName()), - errMsg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - - updateContent(); - } - } -} - -void VSnippetList::handleContextMenuRequested(QPoint p_pos) -{ - QListWidgetItem *item = m_snippetList->itemAt(p_pos); - QMenu menu(this); - menu.setToolTipsVisible(true); - - if (item) { - int itemCount = m_snippetList->selectedItems().size(); - if (itemCount == 1) { - menu.addAction(m_applyAct); - menu.addAction(m_infoAct); - } - - menu.addAction(m_deleteAct); - } - - m_snippetList->update(); - - if (m_snippets.size() > 1) { - if (!menu.actions().isEmpty()) { - menu.addSeparator(); - } - - menu.addAction(m_sortAct); - } - - if (!menu.actions().isEmpty()) { - menu.exec(m_snippetList->mapToGlobal(p_pos)); - } -} - -void VSnippetList::handleItemActivated(QListWidgetItem *p_item) -{ - const VSnippet *snip = getSnippet(p_item); - if (snip) { - VEditTab *tab = g_mainWin->getCurrentTab(); - if (tab) { - tab->applySnippet(snip); - } - } -} - -void VSnippetList::deleteSelectedItems() -{ - QVector items; - const QList selectedItems = m_snippetList->selectedItems(); - - if (selectedItems.isEmpty()) { - return; - } - - for (auto const & item : selectedItems) { - QString name = item->data(Qt::UserRole).toString(); - items.push_back(ConfirmItemInfo(name, - name, - "", - NULL)); - } - - QString text = tr("Are you sure to delete these snippets?"); - QString info = tr("Click \"Cancel\" to leave them untouched."); - VConfirmDeletionDialog dialog(tr("Confirm Deleting Snippets"), - text, - info, - items, - false, - false, - false, - this); - if (dialog.exec()) { - items = dialog.getConfirmedItems(); - - QList names; - for (auto const & item : items) { - names.append(item.m_name); - } - - QString errMsg; - if (!deleteSnippets(names, &errMsg)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to delete snippets."), - errMsg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - updateContent(); - } -} - -void VSnippetList::sortItems() -{ - if (m_snippets.size() < 2) { - return; - } - - VSortDialog dialog(tr("Sort Snippets"), - tr("Sort snippets in the configuration file."), - this); - QTreeWidget *tree = dialog.getTreeWidget(); - tree->clear(); - tree->setColumnCount(1); - QStringList headers; - headers << tr("Name"); - tree->setHeaderLabels(headers); - - for (int i = 0; i < m_snippets.size(); ++i) { - QTreeWidgetItem *item = new QTreeWidgetItem(tree, QStringList(m_snippets[i].getName())); - - item->setData(0, Qt::UserRole, i); - } - - dialog.treeUpdated(); - - if (dialog.exec()) { - QVector data = dialog.getSortedData(); - Q_ASSERT(data.size() == m_snippets.size()); - QVector sortedIdx(data.size(), -1); - for (int i = 0; i < data.size(); ++i) { - sortedIdx[i] = data[i].toInt(); - } - - QString errMsg; - if (!sortSnippets(sortedIdx, &errMsg)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to sort snippets."), - errMsg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - updateContent(); - } -} - -void VSnippetList::snippetInfo() -{ - if (m_snippetList->selectedItems().size() != 1) { - return; - } - - QListWidgetItem *item = m_snippetList->currentItem(); - VSnippet *snip = getSnippet(item); - if (!snip) { - return; - } - - QString info = tr("Magic words are supported in the content of the snippet."); - VEditSnippetDialog dialog(tr("Snippet Information"), - info, - m_snippets, - *snip, - this); - if (dialog.exec() == QDialog::Accepted) { - QString errMsg; - bool ret = true; - if (snip->getName() != dialog.getNameInput()) { - // Delete the original snippet file. - if (!deleteSnippetFile(*snip, &errMsg)) { - ret = false; - } - } - - if (snip->update(dialog.getNameInput(), - dialog.getTypeInput(), - dialog.getContentInput(), - dialog.getCursorMarkInput(), - dialog.getSelectionMarkInput(), - dialog.getShortcutInput(), - dialog.getAutoIndentInput())) { - if (!writeSnippetFile(*snip, &errMsg)) { - ret = false; - } - - if (!writeSnippetsToConfig()) { - VUtils::addErrMsg(&errMsg, - tr("Fail to write snippets configuration file.")); - ret = false; - } - - updateContent(); - } - - if (!ret) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to update information of snippet %2.") - .arg(g_config->c_dataTextStyle) - .arg(snip->getName()), - errMsg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - } -} - -void VSnippetList::makeSureFolderExist() const -{ - QString path = g_config->getSnippetConfigFolder(); - if (!QFileInfo::exists(path)) { - QDir dir; - dir.mkpath(path); - } -} - -void VSnippetList::updateContent() -{ - m_snippetList->clear(); - - for (int i = 0; i < m_snippets.size(); ++i) { - const VSnippet &snip = m_snippets[i]; - QString text = QString("%1%2").arg(snip.getName()) - .arg(snip.getShortcut().isNull() - ? "" : QString(" [%1]").arg(snip.getShortcut())); - QListWidgetItem *item = new QListWidgetItem(text); - item->setToolTip(snip.getName()); - item->setData(Qt::UserRole, snip.getName()); - - m_snippetList->addItem(item); - } - - int cnt = m_snippetList->count(); - if (cnt > 0) { - m_numLabel->setText(tr("%1 %2").arg(cnt) - .arg(cnt > 1 ? tr("Snippets") : tr("Snippet"))); - m_snippetList->setFocus(); - } else { - m_numLabel->setText(""); - m_addBtn->setFocus(); - } -} - -bool VSnippetList::addSnippet(const VSnippet &p_snippet, QString *p_errMsg) -{ - if (!writeSnippetFile(p_snippet, p_errMsg)) { - return false; - } - - m_snippets.push_back(p_snippet); - - bool ret = true; - if (!writeSnippetsToConfig()) { - VUtils::addErrMsg(p_errMsg, - tr("Fail to write snippets configuration file.")); - m_snippets.pop_back(); - ret = false; - } - - updateContent(); - - return ret; -} - -bool VSnippetList::writeSnippetsToConfig() const -{ - makeSureFolderExist(); - - QJsonObject snippetJson; - snippetJson[SnippetConfig::c_version] = "1"; - - QJsonArray snippetArray; - for (int i = 0; i < m_snippets.size(); ++i) { - snippetArray.append(m_snippets[i].toJson()); - } - - snippetJson[SnippetConfig::c_snippets] = snippetArray; - - return VUtils::writeJsonToDisk(g_config->getSnippetConfigFilePath(), - snippetJson); -} - -bool VSnippetList::readSnippetsFromConfig() -{ - m_snippets.clear(); - - if (!QFileInfo::exists(g_config->getSnippetConfigFilePath())) { - return true; - } - - QJsonObject snippets = VUtils::readJsonFromDisk(g_config->getSnippetConfigFilePath()); - if (snippets.isEmpty()) { - qWarning() << "invalid snippets configuration file" << g_config->getSnippetConfigFilePath(); - return false; - } - - // [snippets] section. - bool ret = true; - QJsonArray snippetArray = snippets[SnippetConfig::c_snippets].toArray(); - for (int i = 0; i < snippetArray.size(); ++i) { - VSnippet snip = VSnippet::fromJson(snippetArray[i].toObject()); - - // Read the content. - QString filePath(QDir(g_config->getSnippetConfigFolder()).filePath(snip.getName())); - QString content = VUtils::readFileFromDisk(filePath); - if (content.isNull()) { - qWarning() << "fail to read snippet" << snip.getName(); - ret = false; - continue; - } - - snip.setContent(content); - m_snippets.push_back(snip); - } - - return ret; -} - -void VSnippetList::keyPressEvent(QKeyEvent *p_event) -{ - if (VimNavigationForWidget::injectKeyPressEventForVim(m_snippetList, - p_event)) { - return; - } - - QWidget::keyPressEvent(p_event); -} - -void VSnippetList::showNavigation() -{ - VNavigationMode::showNavigation(m_snippetList); -} - -bool VSnippetList::handleKeyNavigation(int p_key, bool &p_succeed) -{ - static bool secondKey = false; - return VNavigationMode::handleKeyNavigation(m_snippetList, - secondKey, - p_key, - p_succeed); -} - -int VSnippetList::getSnippetIndex(QListWidgetItem *p_item) const -{ - if (!p_item) { - return -1; - } - - QString name = p_item->data(Qt::UserRole).toString(); - for (int i = 0; i < m_snippets.size(); ++i) { - if (m_snippets[i].getName() == name) { - return i; - } - } - - Q_ASSERT(false); - return -1; -} - -VSnippet *VSnippetList::getSnippet(QListWidgetItem *p_item) -{ - int idx = getSnippetIndex(p_item); - if (idx == -1) { - return NULL; - } else { - return &m_snippets[idx]; - } -} - -bool VSnippetList::writeSnippetFile(const VSnippet &p_snippet, QString *p_errMsg) -{ - // Create and write to the snippet file. - QString filePath = getSnippetFilePath(p_snippet); - if (!VUtils::writeFileToDisk(filePath, p_snippet.getContent())) { - VUtils::addErrMsg(p_errMsg, - tr("Fail to add write the snippet file %1.") - .arg(filePath)); - return false; - } - - return true; -} - -QString VSnippetList::getSnippetFilePath(const VSnippet &p_snippet) const -{ - return QDir(g_config->getSnippetConfigFolder()).filePath(p_snippet.getName()); -} - -bool VSnippetList::sortSnippets(const QVector &p_sortedIdx, QString *p_errMsg) -{ - V_ASSERT(p_sortedIdx.size() == m_snippets.size()); - - auto ori = m_snippets; - - for (int i = 0; i < p_sortedIdx.size(); ++i) { - m_snippets[i] = ori[p_sortedIdx[i]]; - } - - bool ret = true; - if (!writeSnippetsToConfig()) { - VUtils::addErrMsg(p_errMsg, - tr("Fail to write snippets configuration file.")); - m_snippets = ori; - ret = false; - } - - return ret; -} - -bool VSnippetList::deleteSnippets(const QList &p_snippets, - QString *p_errMsg) -{ - if (p_snippets.isEmpty()) { - return true; - } - - bool ret = true; - QSet targets = QSet::fromList(p_snippets); - for (auto it = m_snippets.begin(); it != m_snippets.end();) { - if (targets.contains(it->getName())) { - // Remove it. - if (!deleteSnippetFile(*it, p_errMsg)) { - ret = false; - } - - it = m_snippets.erase(it); - } else { - ++it; - } - } - - if (!writeSnippetsToConfig()) { - VUtils::addErrMsg(p_errMsg, - tr("Fail to write snippets configuration file.")); - ret = false; - } - - return ret; -} - -bool VSnippetList::deleteSnippetFile(const VSnippet &p_snippet, QString *p_errMsg) -{ - QString filePath = getSnippetFilePath(p_snippet); - if (!VUtils::deleteFile(filePath)) { - VUtils::addErrMsg(p_errMsg, - tr("Fail to remove snippet file %1.") - .arg(filePath)); - return false; - } - - return true; -} - -void VSnippetList::focusInEvent(QFocusEvent *p_event) -{ - QWidget::focusInEvent(p_event); - - if (m_snippets.isEmpty()) { - m_addBtn->setFocus(); - } else { - m_snippetList->setFocus(); - } -} diff --git a/src/vsnippetlist.h b/src/vsnippetlist.h deleted file mode 100644 index daa307f1..00000000 --- a/src/vsnippetlist.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef VSNIPPETLIST_H -#define VSNIPPETLIST_H - -#include -#include -#include - -#include "vsnippet.h" -#include "vnavigationmode.h" - -class QPushButton; -class QListWidget; -class QListWidgetItem; -class QLabel; -class QAction; -class QKeyEvent; -class QFocusEvent; - - -class VSnippetList : public QWidget, public VNavigationMode -{ - Q_OBJECT -public: - explicit VSnippetList(QWidget *p_parent = nullptr); - - const QVector &getSnippets() const; - - const VSnippet *getSnippet(const QString &p_name) const; - - // Implementations for VNavigationMode. - void showNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - -protected: - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - - void focusInEvent(QFocusEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - void newSnippet(); - - void handleContextMenuRequested(QPoint p_pos); - - void handleItemActivated(QListWidgetItem *p_item); - - void snippetInfo(); - - void deleteSelectedItems(); - - void sortItems(); - -private: - void setupUI(); - - void initActions(); - - void initShortcuts(); - - void makeSureFolderExist() const; - - // Update list of snippets according to m_snippets. - void updateContent(); - - // Add @p_snippet. - bool addSnippet(const VSnippet &p_snippet, QString *p_errMsg = nullptr); - - // Write m_snippets to config file. - bool writeSnippetsToConfig() const; - - // Read from config file to m_snippets. - bool readSnippetsFromConfig(); - - // Get the snippet index in m_snippets of @p_item. - int getSnippetIndex(QListWidgetItem *p_item) const; - - VSnippet *getSnippet(QListWidgetItem *p_item); - - // Write the content of @p_snippet to file. - bool writeSnippetFile(const VSnippet &p_snippet, QString *p_errMsg = nullptr); - - QString getSnippetFilePath(const VSnippet &p_snippet) const; - - // Sort m_snippets according to @p_sortedIdx. - bool sortSnippets(const QVector &p_sortedIdx, QString *p_errMsg = nullptr); - - bool deleteSnippets(const QList &p_snippets, QString *p_errMsg = nullptr); - - bool deleteSnippetFile(const VSnippet &p_snippet, QString *p_errMsg = nullptr); - - QPushButton *m_addBtn; - QPushButton *m_locateBtn; - QLabel *m_numLabel; - QListWidget *m_snippetList; - - QAction *m_applyAct; - QAction *m_infoAct; - QAction *m_deleteAct; - QAction *m_sortAct; - - QVector m_snippets; - - static const QString c_infoShortcutSequence; -}; - -inline const QVector &VSnippetList::getSnippets() const -{ - return m_snippets; -} - -inline const VSnippet *VSnippetList::getSnippet(const QString &p_name) const -{ - for (auto const & snip : m_snippets) { - if (snip.getName() == p_name) { - return &snip; - } - } - - return NULL; -} -#endif // VSNIPPETLIST_H diff --git a/src/vstyleparser.cpp b/src/vstyleparser.cpp deleted file mode 100644 index 5dce82f9..00000000 --- a/src/vstyleparser.cpp +++ /dev/null @@ -1,325 +0,0 @@ -#include "vstyleparser.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -VStyleParser::VStyleParser() -{ - markdownStyles = NULL; -} - -VStyleParser::~VStyleParser() -{ - if (markdownStyles) { - pmh_free_style_collection(markdownStyles); - } -} - -QColor VStyleParser::QColorFromPmhAttr(pmh_attr_argb_color *attr) const -{ - return QColor(attr->red, attr->green, attr->blue, attr->alpha); -} - -QBrush VStyleParser::QBrushFromPmhAttr(pmh_attr_argb_color *attr) const -{ - return QBrush(QColorFromPmhAttr(attr)); -} - -void markdownStyleErrorCB(char *errMsg, int lineNr, void *context) -{ - (void)context; - qWarning() << "parser error:" << errMsg << lineNr; -} - -QTextCharFormat VStyleParser::QTextCharFormatFromAttrs(pmh_style_attribute *attrs, - const QFont &baseFont) const -{ - QTextCharFormat format; - while (attrs) { - switch (attrs->type) { - case pmh_attr_type_foreground_color: - format.setForeground(QBrushFromPmhAttr(attrs->value->argb_color)); - break; - - case pmh_attr_type_background_color: - format.setBackground(QBrushFromPmhAttr(attrs->value->argb_color)); - break; - - case pmh_attr_type_font_size_pt: - { - pmh_attr_font_size *fontSize = attrs->value->font_size; - int ptSize = fontSize->size_pt; - if (fontSize->is_relative) { - int basePtSize = baseFont.pointSize(); - if (basePtSize == -1) { - // In pixel. Use default font configuration. - basePtSize = 11; - } - ptSize += basePtSize; - } - if (ptSize > 0) { - format.setFontPointSize(ptSize); - } - break; - } - - case pmh_attr_type_font_family: - { - QString familyList(attrs->value->font_family); - QString finalFamily = filterAvailableFontFamily(familyList); - if (!finalFamily.isEmpty()) { - format.setFontFamily(finalFamily); - } - break; - } - - case pmh_attr_type_font_style: - { - pmh_attr_font_styles *fontStyle = attrs->value->font_styles; - if (fontStyle->italic) { - format.setFontItalic(true); - } - if (fontStyle->bold) { - format.setFontWeight(QFont::Bold); - } - if (fontStyle->underlined) { - format.setFontUnderline(true); - } - break; - } - - default: - qWarning() << "unimplemented format attr type:" << attrs->type; - break; - } - attrs = attrs->next; - } - return format; -} - -void VStyleParser::parseMarkdownStyle(const QString &styleStr) -{ - if (markdownStyles) { - pmh_free_style_collection(markdownStyles); - } - markdownStyles = pmh_parse_styles(styleStr.toLocal8Bit().data(), - &markdownStyleErrorCB, this); -} - -QVector VStyleParser::fetchMarkdownStyles(const QFont &baseFont) const -{ - QVector styles; - - for (int i = 0; i < pmh_NUM_LANG_TYPES; ++i) { - pmh_style_attribute *attr = markdownStyles->element_styles[i]; - if (!attr) { - continue; - } - HighlightingStyle style; - style.type = attr->lang_element_type; - style.format = QTextCharFormatFromAttrs(attr, baseFont); - styles.append(style); - } - return styles; -} - -QHash VStyleParser::fetchCodeBlockStyles(const QFont & p_baseFont) const -{ - QHash styles; - - pmh_style_attribute *attrs = markdownStyles->element_styles[pmh_VERBATIM]; - - // First set up the base format. - QTextCharFormat baseFormat = QTextCharFormatFromAttrs(attrs, p_baseFont); - - while (attrs) { - switch (attrs->type) { - case pmh_attr_type_other: - { - QString attrName(attrs->name); - QString attrValue(attrs->value->string); - QTextCharFormat format; - format.setFontFamily(baseFormat.fontFamily()); - - QStringList items = attrValue.split(',', QString::SkipEmptyParts); - for (auto const &item : items) { - QString val = item.trimmed().toLower(); - if (val == "bold") { - format.setFontWeight(QFont::Bold); - } else if (val == "italic") { - format.setFontItalic(true); - } else if (val == "underlined") { - format.setFontUnderline(true); - } else { - // Treat it as the color RGB value string without '#'. - QColor color("#" + val); - if (color.isValid()) { - format.setForeground(QBrush(color)); - } - } - } - - if (format.isValid()) { - styles[attrName] = format; - } - break; - } - - default: - // We just only handle custom attribute here. - break; - } - attrs = attrs->next; - } - - return styles; -} - -void VStyleParser::fetchMarkdownEditorStyles(QPalette &palette, QFont &font, - QMap> &styles) const -{ - QString ruleKey; - - int basePointSize = font.pointSize(); - if (basePointSize == -1) { - // The size is specified in pixel. Use 11 pt by default. - basePointSize = 11; - } - - // editor - pmh_style_attribute *editorStyles = markdownStyles->editor_styles; - ruleKey = "editor"; - while (editorStyles) { - switch (editorStyles->type) { - case pmh_attr_type_foreground_color: - palette.setColor(QPalette::Text, - QColorFromPmhAttr(editorStyles->value->argb_color)); - break; - - case pmh_attr_type_background_color: - palette.setColor(QPalette::Base, - QColorFromPmhAttr(editorStyles->value->argb_color)); - break; - - case pmh_attr_type_font_family: - { - QString familyList(editorStyles->value->font_family); - QString finalFamily = filterAvailableFontFamily(familyList); - if (!finalFamily.isEmpty()) { - font.setFamily(finalFamily); - } - break; - } - - case pmh_attr_type_font_size_pt: - { - pmh_attr_font_size *fontSize = editorStyles->value->font_size; - int ptSize = fontSize->size_pt; - if (fontSize->is_relative) { - ptSize += basePointSize; - } - - if (ptSize > 0) { - font.setPointSize(ptSize); - } - - break; - } - - // Get custom styles: - // trailing-space, line-number-background, line-number-foreground, - // color-column-background, color-column-foreground - case pmh_attr_type_other: - { - QString attrName(editorStyles->name); - QString value(editorStyles->value->string); - styles[ruleKey][attrName] = value; - break; - } - - default: - qWarning() << "unimplemented editor attr type:" << editorStyles->type; - } - editorStyles = editorStyles->next; - } - - // editor-current-line - pmh_style_attribute *curLineStyles = markdownStyles->editor_current_line_styles; - ruleKey = "editor-current-line"; - while (curLineStyles) { - switch (curLineStyles->type) { - case pmh_attr_type_background_color: - { - QString attrName(curLineStyles->name); - QString value = QColorFromPmhAttr(curLineStyles->value->argb_color).name(); - styles[ruleKey][attrName] = value; - break; - } - - // Get custom styles: - // vim-background. - case pmh_attr_type_other: - { - QString attrName(curLineStyles->name); - QString value(curLineStyles->value->string); - styles[ruleKey][attrName] = value; - break; - } - - default: - qWarning() << "unimplemented current line attr type:" << curLineStyles->type; - } - curLineStyles = curLineStyles->next; - } - - // editor-selection - pmh_style_attribute *selStyles = markdownStyles->editor_selection_styles; - while (selStyles) { - switch (selStyles->type) { - case pmh_attr_type_foreground_color: - palette.setColor(QPalette::HighlightedText, - QColorFromPmhAttr(selStyles->value->argb_color)); - break; - - case pmh_attr_type_background_color: - palette.setColor(QPalette::Highlight, - QColorFromPmhAttr(selStyles->value->argb_color)); - break; - - default: - qWarning() << "unimplemented selection attr type:" << selStyles->type; - } - selStyles = selStyles->next; - } -} - -// @familyList is a comma separated string -QString VStyleParser::filterAvailableFontFamily(const QString &familyList) const -{ - QStringList families = familyList.split(',', QString::SkipEmptyParts); - QStringList availFamilies = QFontDatabase().families(); - - qDebug() << "family:" << familyList; - for (int i = 0; i < families.size(); ++i) { - QString family = families[i].trimmed(); - for (int j = 0; j < availFamilies.size(); ++j) { - QString availFamily = availFamilies[j]; - availFamily.remove(QRegExp("\\[.*\\]")); - availFamily = availFamily.trimmed(); - if (family == availFamily - || family.toLower() == availFamily.toLower()) { - qDebug() << "matched family:" << availFamilies[j]; - return availFamilies[j]; - } - } - } - - return QString(); -} diff --git a/src/vstyleparser.h b/src/vstyleparser.h deleted file mode 100644 index f7a49d37..00000000 --- a/src/vstyleparser.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef VSTYLEPARSER_H -#define VSTYLEPARSER_H - -#include -#include -#include -#include -#include "hgmarkdownhighlighter.h" - -extern "C" { -#include -#include -} - -class QColor; -class QBrush; - -class VStyleParser -{ -public: - VStyleParser(); - ~VStyleParser(); - - void parseMarkdownStyle(const QString &styleStr); - QVector fetchMarkdownStyles(const QFont &baseFont) const; - - // Fetch style sections: editor, editor-selection, editor-current-line. - // @styles: [rule] -> ([attr] -> value). - void fetchMarkdownEditorStyles(QPalette &palette, QFont &font, - QMap> &styles) const; - - QHash fetchCodeBlockStyles(const QFont &p_baseFont) const; - -private: - QColor QColorFromPmhAttr(pmh_attr_argb_color *attr) const; - QBrush QBrushFromPmhAttr(pmh_attr_argb_color *attr) const; - QTextCharFormat QTextCharFormatFromAttrs(pmh_style_attribute *attrs, - const QFont &baseFont) const; - QString filterAvailableFontFamily(const QString &familyList) const; - pmh_style_collection *markdownStyles; -}; - -#endif // VSTYLEPARSER_H diff --git a/src/vtabindicator.cpp b/src/vtabindicator.cpp deleted file mode 100644 index 5361f93b..00000000 --- a/src/vtabindicator.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "vtabindicator.h" - -#include -#include - -#include "vedittab.h" -#include "vorphanfile.h" - -VTabIndicator::VTabIndicator(QWidget *p_parent) - : QWidget(p_parent) -{ - setupUI(); -} - -void VTabIndicator::setupUI() -{ - m_docTypeLabel = new QLabel(this); - m_docTypeLabel->setToolTip(tr("The type of the file")); - m_docTypeLabel->setProperty("ColorGreyLabel", true); - - m_readonlyLabel = new QLabel(tr("ReadOnly"), this); - m_readonlyLabel->setToolTip(tr("This file is read-only")); - m_readonlyLabel->setProperty("ColorRedLabel", true); - - m_externalLabel = new QLabel(tr("Standalone"), this); - m_externalLabel->setToolTip(tr("This file is not managed by any notebook or folder")); - m_externalLabel->setProperty("ColorTealLabel", true); - - m_systemLabel = new QLabel(tr("System"), this); - m_systemLabel->setToolTip(tr("This file is a system file")); - m_systemLabel->setProperty("ColorGreenLabel", true); - - m_cursorLabel = new QLabel(this); - m_cursorLabel->setProperty("TabIndicatorLabel", true); - - QHBoxLayout *mainLayout = new QHBoxLayout(this); - mainLayout->addWidget(m_cursorLabel); - mainLayout->addWidget(m_externalLabel); - mainLayout->addWidget(m_systemLabel); - mainLayout->addWidget(m_readonlyLabel); - mainLayout->addWidget(m_docTypeLabel); - mainLayout->setContentsMargins(0, 0, 0, 0); - - setLayout(mainLayout); -} - -static QString docTypeToString(DocType p_type) -{ - QString str; - - switch (p_type) { - case DocType::Html: - str = "HTML"; - break; - - case DocType::Markdown: - str = "Markdown"; - break; - - case DocType::List: - str = "List"; - break; - - case DocType::Container: - str = "Container"; - break; - - default: - str = "Unknown"; - break; - } - - return str; -} - -void VTabIndicator::update(const VEditTabInfo &p_info) -{ - const VEditTab *editTab = NULL; - const VFile *file = NULL; - DocType docType = DocType::Html; - bool readonly = false; - bool external = false; - bool system = false; - QString cursorStr; - - if (p_info.m_editTab) - { - editTab = p_info.m_editTab; - file = editTab->getFile(); - docType = file->getDocType(); - readonly = !file->isModifiable(); - external = file->getType() == FileType::Orphan; - system = external && dynamic_cast(file)->isSystemFile(); - - if (editTab->isEditMode()) { - int line = p_info.m_cursorBlockNumber + 1; - int col = p_info.m_cursorPositionInBlock; - if (col < 0) { - col = 0; - } - - int lineCount = p_info.m_blockCount < 1 ? 1 : p_info.m_blockCount; - - QString cursorText = tr("Line: %1 - %2(%3%) " - "Col: %4") - .arg(line).arg(lineCount) - .arg((int)(line * 1.0 / lineCount * 100), 2) - .arg(col, 3); - m_cursorLabel->setText(cursorText); - m_cursorLabel->show(); - } else { - m_cursorLabel->hide(); - } - } - - m_docTypeLabel->setText(docTypeToString(docType)); - m_readonlyLabel->setVisible(readonly); - m_externalLabel->setVisible(external); - m_systemLabel->setVisible(system); -} diff --git a/src/vtabindicator.h b/src/vtabindicator.h deleted file mode 100644 index b029eaa8..00000000 --- a/src/vtabindicator.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef VTABINDICATOR_H -#define VTABINDICATOR_H - -#include -#include "vedittabinfo.h" - -class QLabel; - -class VTabIndicator : public QWidget -{ - Q_OBJECT - -public: - explicit VTabIndicator(QWidget *p_parent = 0); - - // Update indicator. - void update(const VEditTabInfo &p_info); - -private: - void setupUI(); - - // Indicate the doc type. - QLabel *m_docTypeLabel; - - // Indicate the readonly property. - QLabel *m_readonlyLabel; - - // Indicate whether it is a normal note or an external file. - QLabel *m_externalLabel; - - // Indicate whether it is a system file. - QLabel *m_systemLabel; - - // Indicate the position of current cursor. - QLabel *m_cursorLabel; -}; - -#endif // VTABINDICATOR_H diff --git a/src/vtableofcontent.cpp b/src/vtableofcontent.cpp deleted file mode 100644 index 396b54ff..00000000 --- a/src/vtableofcontent.cpp +++ /dev/null @@ -1,190 +0,0 @@ -#include "vtableofcontent.h" -#include "vconstants.h" - -#include -#include - - -VTableOfContent::VTableOfContent() - : m_file(NULL), m_type(VTableOfContentType::Anchor) -{ -} - -VTableOfContent::VTableOfContent(const VFile *p_file) - : m_file(p_file), m_type(VTableOfContentType::Anchor) -{ -} - -void VTableOfContent::update(const VFile *p_file, - const QVector &p_table, - VTableOfContentType p_type) -{ - m_file = p_file; - m_table = p_table; - m_type = p_type; -} - -static bool parseTocUl(QXmlStreamReader &p_xml, - QVector &p_table, - int p_level); - -static bool parseTocLi(QXmlStreamReader &p_xml, - QVector &p_table, - int p_level) -{ - Q_ASSERT(p_xml.isStartElement() && p_xml.name() == "li"); - - if (p_xml.readNextStartElement()) { - if (p_xml.name() == "a") { - QString anchor = p_xml.attributes().value("href").toString().mid(1); - QString name; - // Read till . - int nrStart = 1; - while (p_xml.readNext()) { - if (p_xml.tokenString() == "Characters") { - name += p_xml.text().toString(); - } else if (p_xml.isEndElement()) { - --nrStart; - if (nrStart < 0) { - qWarning() << "end elements more than start elements in " << anchor << p_xml.name(); - return false; - } - - if (p_xml.name() == "a") { - break; - } - } else if (p_xml.isStartElement()) { - ++nrStart; - } - } - - if (p_xml.hasError()) { - // Error - qWarning() << "fail to parse an entire element" << anchor << name; - return false; - } - - VTableOfContentItem header(name, p_level, anchor, p_table.size()); - p_table.append(header); - } else if (p_xml.name() == "ul") { - // Such as header 3 under header 1 directly - VTableOfContentItem header(c_emptyHeaderName, p_level, "", p_table.size()); - p_table.append(header); - parseTocUl(p_xml, p_table, p_level + 1); - } else { - qWarning() << "TOC HTML

  • should contain or
      " << p_xml.name(); - return false; - } - } - - while (p_xml.readNext()) { - if (p_xml.isEndElement()) { - if (p_xml.name() == "li") { - return true; - } - - continue; - } - - if (p_xml.name() == "ul") { - // Nested unordered list - if (!parseTocUl(p_xml, p_table, p_level + 1)) { - return false; - } - } else { - return false; - } - } - - return true; -} - -static bool parseTocUl(QXmlStreamReader &p_xml, - QVector &p_table, - int p_level) -{ - bool ret = true; - Q_ASSERT(p_xml.isStartElement() && p_xml.name() == "ul"); - - while (p_xml.readNextStartElement()) { - if (p_xml.name() == "li") { - if (!parseTocLi(p_xml, p_table, p_level)) { - ret = false; - break; - } - } else { - qWarning() << "TOC HTML
        should contain
      • " << p_xml.name(); - ret = false; - break; - } - } - - return ret; -} - -bool VTableOfContent::parseTableFromHtml(const QString &p_html) -{ - bool ret = true; - m_table.clear(); - - if (!p_html.isEmpty()) { - QXmlStreamReader xml(p_html); - if (xml.readNextStartElement()) { - if (xml.name() == "ul") { - ret = parseTocUl(xml, m_table, 1); - } else { - qWarning() << "TOC HTML does not start with
          " << p_html; - ret = false; - } - } - - if (xml.hasError()) { - qWarning() << "fail to parse TOC in HTML" << p_html; - ret = false; - } - } - - return ret; -} - -int VTableOfContent::indexOfItemByAnchor(const QString &p_anchor) const -{ - if (p_anchor.isEmpty() - || isEmpty() - || m_type != VTableOfContentType::Anchor) { - return -1; - } - - for (int i = 0; i < m_table.size(); ++i) { - if (m_table[i].m_anchor == p_anchor) { - return i; - } - } - - return -1; -} - -int VTableOfContent::indexOfItemByBlockNumber(int p_blockNumber) const -{ - if (p_blockNumber == -1 - || isEmpty() - || m_type != VTableOfContentType::BlockNumber) { - return -1; - } - - for (int i = m_table.size() - 1; i >= 0; --i) { - if (!m_table[i].isEmpty() - && m_table[i].m_blockNumber <= p_blockNumber) { - return i; - } - } - - return -1; -} - -bool VTableOfContent::operator==(const VTableOfContent &p_outline) const -{ - return m_file == p_outline.getFile() - && m_type == p_outline.getType() - && m_table == p_outline.getTable(); -} diff --git a/src/vtableofcontent.h b/src/vtableofcontent.h deleted file mode 100644 index 5f589e75..00000000 --- a/src/vtableofcontent.h +++ /dev/null @@ -1,286 +0,0 @@ -#ifndef VTABLEOFCONTENT_H -#define VTABLEOFCONTENT_H - -#include -#include - -class VFile; - - -struct VHeaderPointer -{ - VHeaderPointer() - : m_file(NULL), m_index(-1) - { - } - - VHeaderPointer(const VFile *p_file, int p_index) - : m_file(p_file), m_index(p_index) - { - } - - bool operator==(const VHeaderPointer &p_header) const - { - return m_file == p_header.m_file - && m_index == p_header.m_index; - } - - void reset() - { - m_index = -1; - } - - void clear() - { - m_file = NULL; - reset(); - } - - void update(const VFile *p_file, int p_index) - { - m_file = p_file; - m_index = p_index; - } - - bool isValid() const - { - return m_index > -1; - } - - QString toString() const - { - return QString("VHeaderPointer file: %1 index: %2") - .arg((long long)m_file) - .arg(m_index); - } - - // The corresponding file. - const VFile *m_file; - - // Index of the header item in VTableOfContent which this instance points to. - int m_index; -}; - - -struct VTableOfContentItem -{ - VTableOfContentItem() - : m_level(1), m_blockNumber(-1), m_index(-1) - { - } - - VTableOfContentItem(const QString &p_name, - int p_level, - const QString &p_anchor, - int p_index) - : m_name(p_name), - m_level(p_level), - m_anchor(p_anchor), - m_blockNumber(-1), - m_index(p_index) - { - } - - VTableOfContentItem(const QString &p_name, - int p_level, - int p_blockNumber, - int p_index) - : m_name(p_name), - m_level(p_level), - m_blockNumber(p_blockNumber), - m_index(p_index) - { - } - - // Whether it is an empty item. - // An empty item points to nothing. - bool isEmpty() const - { - if (m_anchor.isEmpty()) { - return m_blockNumber == -1; - } - - return false; - } - - bool isMatched(const VHeaderPointer &p_header) const - { - return m_index == p_header.m_index; - } - - bool operator==(const VTableOfContentItem &p_item) const - { - return m_name == p_item.m_name - && m_level == p_item.m_level - && m_anchor == p_item.m_anchor - && m_blockNumber == p_item.m_blockNumber - && m_index == p_item.m_index; - } - - // Name of the item to display. - QString m_name; - - // Level of this item, based on 1. - int m_level; - - // Use an anchor to identify the position of this item. - QString m_anchor; - - // Use block number to identify the position of this item. - // -1 to indicate invalid. - int m_blockNumber; - - // Index in VTableOfContent, based on 0. - // -1 for invalid value. - int m_index; -}; - - -enum class VTableOfContentType -{ - Anchor = 0, - BlockNumber -}; - - -class VTableOfContent -{ -public: - VTableOfContent(); - - VTableOfContent(const VFile *p_file); - - void update(const VFile *p_file, - const QVector &p_table, - VTableOfContentType p_type); - - // Parse m_table from html. - bool parseTableFromHtml(const QString &p_html); - - const VFile *getFile() const; - - void setFile(const VFile *p_file); - - VTableOfContentType getType() const; - - void setType(VTableOfContentType p_type); - - void clearTable(); - - const QVector &getTable() const; - - void setTable(const QVector &p_table); - - void clear(); - - // Return the index in @m_table of @p_anchor. - int indexOfItemByAnchor(const QString &p_anchor) const; - - // Return the last index in @m_table which has smaller block number than @p_blockNumber. - int indexOfItemByBlockNumber(int p_blockNumber) const; - - const VTableOfContentItem *getItem(int p_idx) const; - - const VTableOfContentItem *getItem(const VHeaderPointer &p_header) const; - - bool isEmpty() const; - - // Whether @p_header is pointing to this outline. - bool isMatched(const VHeaderPointer &p_header) const; - - bool operator==(const VTableOfContent &p_outline) const; - - QString toString() const; - -private: - // Corresponding file. - const VFile *m_file; - - // Table of content. - QVector m_table; - - // Type of the table of content: by anchor or by block number. - VTableOfContentType m_type; -}; - -inline VTableOfContentType VTableOfContent::getType() const -{ - return m_type; -} - -inline void VTableOfContent::setType(VTableOfContentType p_type) -{ - m_type = p_type; -} - -inline void VTableOfContent::clearTable() -{ - m_table.clear(); -} - -inline const QVector &VTableOfContent::getTable() const -{ - return m_table; -} - -inline void VTableOfContent::setTable(const QVector &p_table) -{ - m_table = p_table; -} - -inline void VTableOfContent::clear() -{ - m_file = NULL; - m_table.clear(); - m_type = VTableOfContentType::Anchor; -} - -inline void VTableOfContent::setFile(const VFile *p_file) -{ - m_file = p_file; -} - -inline const VFile *VTableOfContent::getFile() const -{ - return m_file; -} - -inline const VTableOfContentItem *VTableOfContent::getItem(int p_idx) const -{ - if (!m_file - || p_idx < 0 - || p_idx >= m_table.size()) { - return NULL; - } - - return &m_table[p_idx]; -} - -inline const VTableOfContentItem *VTableOfContent::getItem(const VHeaderPointer &p_header) const -{ - if (p_header.m_file != m_file) { - return NULL; - } - - return getItem(p_header.m_index); -} - -inline bool VTableOfContent::isEmpty() const -{ - return !m_file || m_table.isEmpty(); -} - -inline bool VTableOfContent::isMatched(const VHeaderPointer &p_header) const -{ - return m_file && m_file == p_header.m_file; -} - -inline QString VTableOfContent::toString() const -{ - return QString("VTableOfContent file: %1 isAnchor: %2 tableSize: %3") - .arg((long long)m_file) - .arg(m_type == VTableOfContentType::Anchor) - .arg(m_table.size()); -} - -#endif // VTABLEOFCONTENT_H diff --git a/src/vtextblockdata.cpp b/src/vtextblockdata.cpp deleted file mode 100644 index a5a0092d..00000000 --- a/src/vtextblockdata.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "vtextblockdata.h" - -#include - -VTextBlockData::VTextBlockData() - : QTextBlockUserData() -{ -} - -VTextBlockData::~VTextBlockData() -{ - for (auto it : m_previews) { - delete it; - } - - m_previews.clear(); -} - -void VTextBlockData::insertPreviewInfo(VPreviewInfo *p_info) -{ - bool inserted = false; - for (auto it = m_previews.begin(); it != m_previews.end();) { - VPreviewInfo *ele = *it; - - if (p_info->m_imageInfo < ele->m_imageInfo) { - // Insert p_info here. - m_previews.insert(it, p_info); - inserted = true; - break; - } else if (p_info->m_imageInfo == ele->m_imageInfo) { - // Update the timestamp. - delete ele; - *it = p_info; - inserted = true; - qDebug() << "update eixsting image's timestamp" << p_info->m_imageInfo.toString(); - break; - } else if (p_info->m_imageInfo.intersect(ele->m_imageInfo)) { - // The new one intersect with an old one. - // Remove the old one. - Q_ASSERT(ele->m_timeStamp < p_info->m_timeStamp); - qDebug() << "remove intersecting old image" << ele->m_imageInfo.toString(); - delete ele; - it = m_previews.erase(it); - } else { - ++it; - } - } - - if (!inserted) { - // Append it. - m_previews.append(p_info); - } - - Q_ASSERT(checkOrder()); -} - -QString VTextBlockData::toString() const -{ - QString ret; - for (int i = 0; i < m_previews.size(); ++i) { - ret += QString("preview %1: source %2 ts %3 image %4\n") - .arg(i) - .arg((int)m_previews[i]->m_source) - .arg(m_previews[i]->m_timeStamp) - .arg(m_previews[i]->m_imageInfo.toString()); - } - - return ret; -} - -bool VTextBlockData::checkOrder() const -{ - for (int i = 1; i < m_previews.size(); ++i) { - if (!(m_previews[i - 1]->m_imageInfo < m_previews[i]->m_imageInfo)) { - return false; - } - } - - return true; -} - -bool VTextBlockData::clearObsoletePreview(long long p_timeStamp, PreviewSource p_source) -{ - bool deleted = false; - for (auto it = m_previews.begin(); it != m_previews.end();) { - VPreviewInfo *ele = *it; - - if (ele->m_source == p_source - && ele->m_timeStamp < p_timeStamp) { - // Remove it. - qDebug() << "clear obsolete preview" << ele->m_imageInfo.toString(); - delete ele; - it = m_previews.erase(it); - deleted = true; - } else { - ++it; - } - } - - return deleted; -} diff --git a/src/vtextblockdata.h b/src/vtextblockdata.h deleted file mode 100644 index 62d45ac6..00000000 --- a/src/vtextblockdata.h +++ /dev/null @@ -1,163 +0,0 @@ -#ifndef VTEXTBLOCKDATA_H -#define VTEXTBLOCKDATA_H - -#include -#include - -// Sources of the preview. -enum class PreviewSource -{ - ImageLink = 0, - MaxNumberOfSources -}; - - -// Info about a previewed image. -struct VPreviewedImageInfo -{ - VPreviewedImageInfo() - : m_startPos(-1), - m_endPos(-1), - m_padding(0), - m_inline(false) - { - } - - VPreviewedImageInfo(int p_startPos, - int p_endPos, - int p_padding, - bool p_inline, - const QString &p_imageName, - const QSize &p_imageSize) - : m_startPos(p_startPos), - m_endPos(p_endPos), - m_padding(p_padding), - m_inline(p_inline), - m_imageName(p_imageName), - m_imageSize(p_imageSize) - { - } - - bool operator<(const VPreviewedImageInfo &a) const - { - return m_endPos <= a.m_startPos; - } - - bool operator==(const VPreviewedImageInfo &a) const - { - return m_startPos == a.m_startPos - && m_endPos == a.m_endPos - && m_padding == a.m_padding - && m_inline == a.m_inline - && m_imageName == a.m_imageName - && m_imageSize == a.m_imageSize; - } - - bool intersect(const VPreviewedImageInfo &a) const - { - return !(m_endPos <= a.m_startPos || m_startPos >= a.m_endPos); - } - - QString toString() const - { - return QString("previewed image (%1): [%2, %3] padding %4 inline %5 (%6,%7)") - .arg(m_imageName) - .arg(m_startPos) - .arg(m_endPos) - .arg(m_padding) - .arg(m_inline) - .arg(m_imageSize.width()) - .arg(m_imageSize.height()); - } - - // Start position of text corresponding to the image within block. - int m_startPos; - - // End position of text corresponding to the image within block. - int m_endPos; - - // Padding of the image. Only valid for block image. - int m_padding; - - // Whether it is inline image or block image. - bool m_inline; - - // Image name in the resource manager. - QString m_imageName; - - // Image size of the image. Cache for performance. - QSize m_imageSize; -}; - - -struct VPreviewInfo -{ - VPreviewInfo() - : m_source(PreviewSource::ImageLink), - m_timeStamp(0) - { - } - - VPreviewInfo(PreviewSource p_source, - long long p_timeStamp, - int p_startPos, - int p_endPos, - int p_padding, - bool p_inline, - const QString &p_imageName, - const QSize &p_imageSize) - : m_source(p_source), - m_timeStamp(p_timeStamp), - m_imageInfo(p_startPos, - p_endPos, - p_padding, - p_inline, - p_imageName, - p_imageSize) - { - } - - // Source of this preview. - PreviewSource m_source; - - // Timestamp for this preview. - long long m_timeStamp; - - // Image info of this preview. - VPreviewedImageInfo m_imageInfo; -}; - - -// User data for each block. -class VTextBlockData : public QTextBlockUserData -{ -public: - VTextBlockData(); - - ~VTextBlockData(); - - // Insert @p_info into m_previews, preserving the order. - void insertPreviewInfo(VPreviewInfo *p_info); - - // For degub only. - QString toString() const; - - const QVector &getPreviews() const; - - // Return true if there have obsolete preview being deleted. - bool clearObsoletePreview(long long p_timeStamp, PreviewSource p_source); - -private: - // Check the order of elements. - bool checkOrder() const; - - // Sorted by m_imageInfo.m_startPos, with no two element's position intersected. - QVector m_previews; -}; - -inline const QVector &VTextBlockData::getPreviews() const -{ - return m_previews; -} - -#endif // VTEXTBLOCKDATA_H diff --git a/src/vtextdocumentlayout.cpp b/src/vtextdocumentlayout.cpp deleted file mode 100644 index 7b47491e..00000000 --- a/src/vtextdocumentlayout.cpp +++ /dev/null @@ -1,1121 +0,0 @@ -#include "vtextdocumentlayout.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vimageresourcemanager2.h" -#include "vtextedit.h" -#include "vtextblockdata.h" - -#define MARKER_THICKNESS 2 -#define MAX_INLINE_IMAGE_HEIGHT 400 - -VTextDocumentLayout::VTextDocumentLayout(QTextDocument *p_doc, - VImageResourceManager2 *p_imageMgr) - : QAbstractTextDocumentLayout(p_doc), - m_margin(p_doc->documentMargin()), - m_width(0), - m_maximumWidthBlockNumber(-1), - m_height(0), - m_lineLeading(0), - m_blockCount(0), - m_cursorWidth(1), - m_cursorMargin(4), - m_imageMgr(p_imageMgr), - m_blockImageEnabled(false), - m_imageWidthConstrainted(false), - m_imageLineColor("#9575CD"), - m_cursorBlockMode(CursorBlock::None), - m_virtualCursorBlockWidth(8), - m_lastCursorBlockWidth(-1), - m_highlightCursorLineBlock(false), - m_cursorLineBlockBg("#C0C0C0"), - m_cursorLineBlockNumber(-1) -{ -} - -static void fillBackground(QPainter *p_painter, - const QRectF &p_rect, - QBrush p_brush, - QRectF p_gradientRect = QRectF()) -{ - p_painter->save(); - if (p_brush.style() >= Qt::LinearGradientPattern - && p_brush.style() <= Qt::ConicalGradientPattern) { - if (!p_gradientRect.isNull()) { - QTransform m = QTransform::fromTranslate(p_gradientRect.left(), - p_gradientRect.top()); - m.scale(p_gradientRect.width(), p_gradientRect.height()); - p_brush.setTransform(m); - const_cast(p_brush.gradient())->setCoordinateMode(QGradient::LogicalMode); - } - } else { - p_painter->setBrushOrigin(p_rect.topLeft()); - } - - p_painter->fillRect(p_rect, p_brush); - p_painter->restore(); -} - -void VTextDocumentLayout::blockRangeFromRect(const QRectF &p_rect, - int &p_first, - int &p_last) const -{ - if (p_rect.isNull()) { - p_first = 0; - p_last = m_blocks.size() - 1; - return; - } - - p_first = -1; - p_last = m_blocks.size() - 1; - int y = p_rect.y(); - Q_ASSERT(document()->blockCount() == m_blocks.size()); - QTextBlock block = document()->firstBlock(); - while (block.isValid()) { - const BlockInfo &info = m_blocks[block.blockNumber()]; - Q_ASSERT(info.hasOffset()); - - if (info.top() == y - || (info.top() < y && info.bottom() >= y)) { - p_first = block.blockNumber(); - break; - } - - block = block.next(); - } - - if (p_first == -1) { - p_last = -1; - return; - } - - y += p_rect.height(); - while (block.isValid()) { - const BlockInfo &info = m_blocks[block.blockNumber()]; - Q_ASSERT(info.hasOffset()); - - if (info.bottom() > y) { - p_last = block.blockNumber(); - break; - } - - block = block.next(); - } -} - -void VTextDocumentLayout::blockRangeFromRectBS(const QRectF &p_rect, - int &p_first, - int &p_last) const -{ - if (p_rect.isNull()) { - p_first = 0; - p_last = m_blocks.size() - 1; - return; - } - - Q_ASSERT(document()->blockCount() == m_blocks.size()); - - p_first = findBlockByPosition(p_rect.topLeft()); - - if (p_first == -1) { - p_last = -1; - return; - } - - int y = p_rect.bottom(); - QTextBlock block = document()->findBlockByNumber(p_first); - - if (m_blocks[p_first].top() == p_rect.top() - && p_first > 0) { - --p_first; - } - - p_last = m_blocks.size() - 1; - while (block.isValid()) { - const BlockInfo &info = m_blocks[block.blockNumber()]; - Q_ASSERT(info.hasOffset()); - - if (info.bottom() > y) { - p_last = block.blockNumber(); - break; - } - - block = block.next(); - } -} - -int VTextDocumentLayout::findBlockByPosition(const QPointF &p_point) const -{ - int first = 0, last = m_blocks.size() - 1; - int y = p_point.y(); - while (first <= last) { - int mid = (first + last) / 2; - const BlockInfo &info = m_blocks[mid]; - Q_ASSERT(info.hasOffset()); - if (info.top() <= y && info.bottom() > y) { - // Found it. - return mid; - } else if (info.top() > y) { - last = mid - 1; - } else { - first = mid + 1; - } - } - - int idx = previousValidBlockNumber(m_blocks.size()); - if (y >= m_blocks[idx].bottom()) { - return idx; - } - - idx = nextValidBlockNumber(-1); - if (y < m_blocks[idx].top()) { - return idx; - } - - Q_ASSERT(false); - return -1; -} - -void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_context) -{ - // Find out the blocks. - int first, last; - blockRangeFromRectBS(p_context.clip, first, last); - if (first == -1) { - return; - } - - QTextDocument *doc = document(); - Q_ASSERT(doc->blockCount() == m_blocks.size()); - QPointF offset(m_margin, m_blocks[first].top()); - QTextBlock block = doc->findBlockByNumber(first); - QTextBlock lastBlock = doc->findBlockByNumber(last); - - QPen oldPen = p_painter->pen(); - p_painter->setPen(p_context.palette.color(QPalette::Text)); - - while (block.isValid()) { - const BlockInfo &info = m_blocks[block.blockNumber()]; - Q_ASSERT(info.hasOffset()); - - const QRectF &rect = info.m_rect; - QTextLayout *layout = block.layout(); - - if (!block.isVisible()) { - offset.ry() += rect.height(); - if (block == lastBlock) { - break; - } - - block = block.next(); - continue; - } - - QTextBlockFormat blockFormat = block.blockFormat(); - QBrush bg = blockFormat.background(); - if (bg != Qt::NoBrush) { - int x = offset.x(); - int y = offset.y(); - fillBackground(p_painter, - rect.adjusted(x, y, x, y), - bg); - } - - auto selections = formatRangeFromSelection(block, p_context.selections); - - // Draw the cursor. - int blpos = block.position(); - int bllen = block.length(); - bool drawCursor = p_context.cursorPosition >= blpos - && p_context.cursorPosition < blpos + bllen; - int cursorWidth = m_cursorWidth; - int cursorPosition = p_context.cursorPosition - blpos; - if (drawCursor && m_cursorBlockMode != CursorBlock::None) { - if (cursorPosition > 0 && m_cursorBlockMode == CursorBlock::LeftSide) { - --cursorPosition; - } - - if (cursorPosition == bllen - 1) { - cursorWidth = m_virtualCursorBlockWidth; - } else { - // Get the width of the selection to update cursor width. - cursorWidth = getTextWidthWithinTextLine(layout, cursorPosition, 1); - if (cursorWidth < m_cursorWidth) { - cursorWidth = m_cursorWidth; - } - } - - if (cursorWidth != m_lastCursorBlockWidth) { - m_lastCursorBlockWidth = cursorWidth; - emit cursorBlockWidthUpdated(m_lastCursorBlockWidth); - } - } - - // Draw cursor line block. - if (m_highlightCursorLineBlock - && m_cursorLineBlockNumber == block.blockNumber()) { - int x = offset.x(); - int y = offset.y(); - fillBackground(p_painter, - rect.adjusted(x, y, x, y), - m_cursorLineBlockBg); - } - - layout->draw(p_painter, - offset, - selections, - p_context.clip.isValid() ? p_context.clip : QRectF()); - - drawImages(p_painter, block, offset); - - drawMarkers(p_painter, block, offset); - - if (drawCursor - || (p_context.cursorPosition < -1 - && !layout->preeditAreaText().isEmpty())) { - if (p_context.cursorPosition < -1) { - cursorPosition = layout->preeditAreaPosition() - - (p_context.cursorPosition + 2); - } - - layout->drawCursor(p_painter, - offset, - cursorPosition, - cursorWidth); - } - - offset.ry() += rect.height(); - if (block == lastBlock) { - break; - } - - block = block.next(); - } - - p_painter->setPen(oldPen); -} - -QVector VTextDocumentLayout::formatRangeFromSelection(const QTextBlock &p_block, - const QVector &p_selections) const -{ - QVector ret; - - int blpos = p_block.position(); - int bllen = p_block.length(); - for (int i = 0; i < p_selections.size(); ++i) { - const QAbstractTextDocumentLayout::Selection &range = p_selections.at(i); - const int selStart = range.cursor.selectionStart() - blpos; - const int selEnd = range.cursor.selectionEnd() - blpos; - if (selStart < bllen - && selEnd > 0 - && selEnd > selStart) { - QTextLayout::FormatRange o; - o.start = selStart; - o.length = selEnd - selStart; - o.format = range.format; - ret.append(o); - } else if (!range.cursor.hasSelection() - && range.format.hasProperty(QTextFormat::FullWidthSelection) - && p_block.contains(range.cursor.position())) { - // For full width selections we don't require an actual selection, just - // a position to specify the line. that's more convenience in usage. - QTextLayout::FormatRange o; - QTextLine l = p_block.layout()->lineForTextPosition(range.cursor.position() - blpos); - Q_ASSERT(l.isValid()); - o.start = l.textStart(); - o.length = l.textLength(); - if (o.start + o.length == bllen - 1) { - ++o.length; // include newline - } - - o.format = range.format; - ret.append(o); - } - } - - return ret; -} - -int VTextDocumentLayout::hitTest(const QPointF &p_point, Qt::HitTestAccuracy p_accuracy) const -{ - Q_UNUSED(p_accuracy); - int bn = findBlockByPosition(p_point); - if (bn == -1) { - return -1; - } - - QTextBlock block = document()->findBlockByNumber(bn); - Q_ASSERT(block.isValid()); - QTextLayout *layout = block.layout(); - int off = 0; - QPointF pos = p_point - QPointF(m_margin, m_blocks[bn].top()); - for (int i = 0; i < layout->lineCount(); ++i) { - QTextLine line = layout->lineAt(i); - const QRectF lr = line.naturalTextRect(); - if (lr.top() > pos.y()) { - off = qMin(off, line.textStart()); - } else if (lr.bottom() <= pos.y()) { - off = qMax(off, line.textStart() + line.textLength()); - } else { - off = line.xToCursor(pos.x(), QTextLine::CursorBetweenCharacters); - break; - } - } - - return block.position() + off; -} - -int VTextDocumentLayout::pageCount() const -{ - return 1; -} - -QSizeF VTextDocumentLayout::documentSize() const -{ - return QSizeF(m_width, m_height); -} - -QRectF VTextDocumentLayout::frameBoundingRect(QTextFrame *p_frame) const -{ - Q_UNUSED(p_frame); - return QRectF(0, 0, - qMax(document()->pageSize().width(), m_width), qreal(INT_MAX)); -} - -QRectF VTextDocumentLayout::blockBoundingRect(const QTextBlock &p_block) const -{ - // Sometimes blockBoundingRect() maybe called before documentChanged(). - if (!p_block.isValid() || p_block.blockNumber() >= m_blocks.size()) { - return QRectF(); - } - - const BlockInfo &info = m_blocks[p_block.blockNumber()]; - QRectF geo = info.m_rect.adjusted(0, info.m_offset, 0, info.m_offset); - Q_ASSERT(info.hasOffset()); - - return geo; -} - -void VTextDocumentLayout::documentChanged(int p_from, int p_charsRemoved, int p_charsAdded) -{ - QTextDocument *doc = document(); - int newBlockCount = doc->blockCount(); - - // Update the margin. - m_margin = doc->documentMargin(); - - int charsChanged = p_charsRemoved + p_charsAdded; - - QTextBlock changeStartBlock = doc->findBlock(p_from); - // May be an invalid block. - QTextBlock changeEndBlock = doc->findBlock(qMax(0, p_from + charsChanged)); - - bool needRelayout = false; - if (changeStartBlock == changeEndBlock - && newBlockCount == m_blockCount) { - // Change single block internal only. - QTextBlock block = changeStartBlock; - if (block.isValid() && block.length()) { - QRectF oldBr = blockBoundingRect(block); - clearBlockLayout(block); - layoutBlock(block); - QRectF newBr = blockBoundingRect(block); - // Only one block is affected. - if (newBr.height() == oldBr.height()) { - // Update document size. - updateDocumentSizeWithOneBlockChanged(block.blockNumber()); - - emit updateBlock(block); - return; - } - } - } else { - // Clear layout of all affected blocks. - QTextBlock block = changeStartBlock; - do { - clearBlockLayout(block); - if (block == changeEndBlock) { - break; - } - - block = block.next(); - } while(block.isValid()); - - needRelayout = true; - } - - updateBlockCount(newBlockCount, changeStartBlock.blockNumber()); - - if (needRelayout) { - // Relayout all affected blocks. - QTextBlock block = changeStartBlock; - do { - layoutBlock(block); - if (block == changeEndBlock) { - break; - } - - block = block.next(); - } while(block.isValid()); - } - - updateDocumentSize(); - - // TODO: Update the view of all the blocks after changeStartBlock. - const BlockInfo &firstInfo = m_blocks[changeStartBlock.blockNumber()]; - emit update(QRectF(0., firstInfo.m_offset, 1000000000., 1000000000.)); -} - -void VTextDocumentLayout::clearBlockLayout(QTextBlock &p_block) -{ - p_block.clearLayout(); - int num = p_block.blockNumber(); - if (num < m_blocks.size()) { - m_blocks[num].reset(); - clearOffsetFrom(num + 1); - } -} - -void VTextDocumentLayout::clearOffsetFrom(int p_blockNumber) -{ - for (int i = p_blockNumber; i < m_blocks.size(); ++i) { - if (!m_blocks[i].hasOffset()) { - Q_ASSERT(validateBlocks()); - break; - } - - m_blocks[i].m_offset = -1; - } -} - -void VTextDocumentLayout::fillOffsetFrom(int p_blockNumber) -{ - qreal offset = m_blocks[p_blockNumber].bottom(); - for (int i = p_blockNumber + 1; i < m_blocks.size(); ++i) { - BlockInfo &info = m_blocks[i]; - if (!info.m_rect.isNull()) { - info.m_offset = offset; - offset += info.m_rect.height(); - } else { - break; - } - } -} - -bool VTextDocumentLayout::validateBlocks() const -{ - bool valid = true; - for (int i = 0; i < m_blocks.size(); ++i) { - const BlockInfo &info = m_blocks[i]; - if (!info.hasOffset()) { - valid = false; - } else if (!valid) { - return false; - } - } - - return true; -} - -void VTextDocumentLayout::updateBlockCount(int p_count, int p_changeStartBlock) -{ - if (m_blockCount != p_count) { - m_blockCount = p_count; - m_blocks.resize(m_blockCount); - - // Fix m_blocks. - QTextBlock block = document()->findBlockByNumber(p_changeStartBlock); - while (block.isValid()) { - BlockInfo &info = m_blocks[block.blockNumber()]; - info.reset(); - - QRectF br = blockRectFromTextLayout(block); - if (!br.isNull()) { - info.m_rect = br; - } - - block = block.next(); - } - } -} - -void VTextDocumentLayout::layoutBlock(const QTextBlock &p_block) -{ - QTextDocument *doc = document(); - Q_ASSERT(m_margin == doc->documentMargin()); - - QTextLayout *tl = p_block.layout(); - QTextOption option = doc->defaultTextOption(); - tl->setTextOption(option); - - int extraMargin = 0; - if (option.flags() & QTextOption::AddSpaceForLineAndParagraphSeparators) { - QFontMetrics fm(p_block.charFormat().font()); - extraMargin += fm.width(QChar(0x21B5)); - } - - qreal availableWidth = doc->pageSize().width(); - if (availableWidth <= 0) { - availableWidth = qreal(INT_MAX); - } - - availableWidth -= (2 * m_margin + extraMargin + m_cursorMargin + m_cursorWidth); - - QVector markers; - QVector images; - - layoutLines(p_block, tl, markers, images, availableWidth, 0); - - // Set this block's line count to its layout's line count. - // That is one block may occupy multiple visual lines. - const_cast(p_block).setLineCount(p_block.isVisible() ? tl->lineCount() : 0); - - // Update the info about this block. - finishBlockLayout(p_block, markers, images); -} - -qreal VTextDocumentLayout::layoutLines(const QTextBlock &p_block, - QTextLayout *p_tl, - QVector &p_markers, - QVector &p_images, - qreal p_availableWidth, - qreal p_height) -{ - // Handle block inline image. - bool hasInlineImages = false; - const QVector *info = NULL; - if (m_blockImageEnabled) { - VTextBlockData *blockData = dynamic_cast(p_block.userData()); - if (blockData) { - info = &(blockData->getPreviews()); - if (!info->isEmpty() - && info->first()->m_imageInfo.m_inline) { - hasInlineImages = true; - } - } - } - - p_tl->beginLayout(); - - int imgIdx = 0; - - while (true) { - QTextLine line = p_tl->createLine(); - if (!line.isValid()) { - break; - } - - line.setLeadingIncluded(true); - line.setLineWidth(p_availableWidth); - p_height += m_lineLeading; - - if (hasInlineImages) { - QVector images; - QVector> imageRange; - qreal imgHeight = fetchInlineImagesForOneLine(*info, - &line, - m_margin, - imgIdx, - images, - imageRange); - - for (int i = 0; i < images.size(); ++i) { - layoutInlineImage(images[i], - p_height, - imgHeight, - imageRange[i].first, - imageRange[i].second, - p_markers, - p_images); - } - - if (!images.isEmpty()) { - p_height += imgHeight + MARKER_THICKNESS + MARKER_THICKNESS; - } - } - - line.setPosition(QPointF(m_margin, p_height)); - p_height += line.height(); - } - - p_tl->endLayout(); - - return p_height; -} - -void VTextDocumentLayout::layoutInlineImage(const VPreviewedImageInfo *p_info, - qreal p_heightInBlock, - qreal p_imageSpaceHeight, - qreal p_xStart, - qreal p_xEnd, - QVector &p_markers, - QVector &p_images) -{ - Marker mk; - qreal mky = p_imageSpaceHeight + p_heightInBlock + MARKER_THICKNESS; - mk.m_start = QPointF(p_xStart, mky); - mk.m_end = QPointF(p_xEnd, mky); - p_markers.append(mk); - - if (p_info) { - QSize size = p_info->m_imageSize; - scaleSize(size, p_xEnd - p_xStart, p_imageSpaceHeight); - - ImagePaintInfo ipi; - ipi.m_name = p_info->m_imageName; - ipi.m_rect = QRectF(QPointF(p_xStart, - p_heightInBlock + p_imageSpaceHeight - size.height()), - size); - p_images.append(ipi); - } -} - -void VTextDocumentLayout::finishBlockLayout(const QTextBlock &p_block, - const QVector &p_markers, - const QVector &p_images) -{ - // Update rect and offset. - Q_ASSERT(p_block.isValid()); - int num = p_block.blockNumber(); - Q_ASSERT(m_blocks.size() > num); - ImagePaintInfo ipi; - BlockInfo &info = m_blocks[num]; - info.reset(); - info.m_rect = blockRectFromTextLayout(p_block, &ipi); - Q_ASSERT(!info.m_rect.isNull()); - int pre = previousValidBlockNumber(num); - if (pre == -1) { - info.m_offset = 0; - } else if (m_blocks[pre].hasOffset()) { - info.m_offset = m_blocks[pre].bottom(); - } - - bool hasImage = false; - if (ipi.isValid()) { - Q_ASSERT(p_markers.isEmpty()); - Q_ASSERT(p_images.isEmpty()); - info.m_images.append(ipi); - hasImage = true; - } else if (!p_markers.isEmpty()) { - // Q_ASSERT(!p_images.isEmpty()); - info.m_markers = p_markers; - info.m_images = p_images; - hasImage = true; - } - - // Add vertical marker. - if (hasImage) { - // Fill the marker. - // Will be adjusted using offset. - Marker mk; - mk.m_start = QPointF(-1, 0); - mk.m_end = QPointF(-1, info.m_rect.height()); - - info.m_markers.append(mk); - } - - if (info.hasOffset()) { - fillOffsetFrom(num); - } -} - -int VTextDocumentLayout::previousValidBlockNumber(int p_number) const -{ - return p_number >= 0 ? p_number - 1 : -1; -} - -int VTextDocumentLayout::nextValidBlockNumber(int p_number) const -{ - if (p_number <= -1) { - return 0; - } else if (p_number >= m_blocks.size() - 1) { - return -1; - } else { - return p_number + 1; - } -} - -void VTextDocumentLayout::updateDocumentSize() -{ - // The last valid block. - int idx = previousValidBlockNumber(m_blocks.size()); - Q_ASSERT(idx > -1); - if (m_blocks[idx].hasOffset()) { - int oldHeight = m_height; - int oldWidth = m_width; - - m_height = m_blocks[idx].bottom(); - - m_width = 0; - for (int i = 0; i < m_blocks.size(); ++i) { - const BlockInfo &info = m_blocks[i]; - Q_ASSERT(info.hasOffset()); - if (m_width < info.m_rect.width()) { - m_width = info.m_rect.width(); - m_maximumWidthBlockNumber = i; - } - } - - if (oldHeight != m_height - || oldWidth != m_width) { - emit documentSizeChanged(documentSize()); - } - } -} - -void VTextDocumentLayout::setCursorWidth(int p_width) -{ - m_cursorWidth = p_width; -} - -int VTextDocumentLayout::cursorWidth() const -{ - return m_cursorWidth; -} - -QRectF VTextDocumentLayout::blockRectFromTextLayout(const QTextBlock &p_block, - ImagePaintInfo *p_image) -{ - if (p_image) { - *p_image = ImagePaintInfo(); - } - - QTextLayout *tl = p_block.layout(); - if (tl->lineCount() < 1) { - return QRectF(); - } - - QRectF tlRect = tl->boundingRect(); - QRectF br(QPointF(0, 0), tlRect.bottomRight()); - - // Do not know why. Copied from QPlainTextDocumentLayout. - if (tl->lineCount() == 1) { - br.setWidth(qMax(br.width(), tl->lineAt(0).naturalTextWidth())); - } - - // Handle block non-inline image. - if (m_blockImageEnabled) { - VTextBlockData *blockData = dynamic_cast(p_block.userData()); - if (blockData) { - const QVector &info = blockData->getPreviews(); - if (info.size() == 1) { - const VPreviewedImageInfo& img = info.first()->m_imageInfo; - if (!img.m_inline) { - int maximumWidth = tlRect.width(); - int padding; - QSize size; - adjustImagePaddingAndSize(&img, maximumWidth, padding, size); - - if (p_image) { - p_image->m_name = img.m_imageName; - p_image->m_rect = QRectF(padding + m_margin, - br.height() + m_lineLeading, - size.width(), - size.height()); - } - - int dw = padding + size.width() + m_margin - br.width(); - int dh = size.height() + m_lineLeading; - br.adjust(0, 0, dw > 0 ? dw : 0, dh); - } - } - } - } - - br.adjust(0, 0, m_margin + m_cursorWidth, 0); - - // Add bottom margin. - if (!p_block.next().isValid()) { - br.adjust(0, 0, 0, m_margin); - } - - return br; -} - -void VTextDocumentLayout::updateDocumentSizeWithOneBlockChanged(int p_blockNumber) -{ - const BlockInfo &info = m_blocks[p_blockNumber]; - qreal width = info.m_rect.width(); - if (width > m_width) { - m_width = width; - m_maximumWidthBlockNumber = p_blockNumber; - emit documentSizeChanged(documentSize()); - } else if (width < m_width && p_blockNumber == m_maximumWidthBlockNumber) { - // Shrink the longest block. - updateDocumentSize(); - } -} - -void VTextDocumentLayout::setLineLeading(qreal p_leading) -{ - if (p_leading >= 0) { - m_lineLeading = p_leading; - } -} - -void VTextDocumentLayout::setImageWidthConstrainted(bool p_enabled) -{ - if (m_imageWidthConstrainted == p_enabled) { - return; - } - - m_imageWidthConstrainted = p_enabled; - relayout(); -} - -void VTextDocumentLayout::setBlockImageEnabled(bool p_enabled) -{ - if (m_blockImageEnabled == p_enabled) { - return; - } - - m_blockImageEnabled = p_enabled; - relayout(); -} - -void VTextDocumentLayout::adjustImagePaddingAndSize(const VPreviewedImageInfo *p_info, - int p_maximumWidth, - int &p_padding, - QSize &p_size) const -{ - const int minimumImageWidth = 400; - - p_padding = p_info->m_padding; - p_size = p_info->m_imageSize; - - if (!m_imageWidthConstrainted) { - return; - } - - int availableWidth = p_maximumWidth - p_info->m_padding; - if (availableWidth < p_info->m_imageSize.width()) { - // Need to resize the width. - if (availableWidth >= minimumImageWidth) { - p_size.scale(availableWidth, p_size.height(), Qt::KeepAspectRatio); - } else { - // Omit the padding. - p_padding = 0; - p_size.scale(p_maximumWidth, p_size.height(), Qt::KeepAspectRatio); - } - } -} - -void VTextDocumentLayout::drawImages(QPainter *p_painter, - const QTextBlock &p_block, - const QPointF &p_offset) -{ - if (m_blocks.size() <= p_block.blockNumber()) { - return; - } - - const QVector &images = m_blocks[p_block.blockNumber()].m_images; - if (images.isEmpty()) { - return; - } - - for (auto const & img : images) { - const QPixmap *image = m_imageMgr->findImage(img.m_name); - if (!image) { - continue; - } - - QRect targetRect = img.m_rect.adjusted(p_offset.x(), - p_offset.y(), - p_offset.x(), - p_offset.y()).toRect(); - - p_painter->drawPixmap(targetRect, *image); - } -} - - -void VTextDocumentLayout::drawMarkers(QPainter *p_painter, - const QTextBlock &p_block, - const QPointF &p_offset) -{ - if (m_blocks.size() <= p_block.blockNumber()) { - return; - } - - const QVector &markers = m_blocks[p_block.blockNumber()].m_markers; - if (markers.isEmpty()) { - return; - } - - QPen oldPen = p_painter->pen(); - QPen newPen(m_imageLineColor, MARKER_THICKNESS, Qt::DashLine); - p_painter->setPen(newPen); - - for (auto const & mk : markers) { - p_painter->drawLine(mk.m_start + p_offset, mk.m_end + p_offset); - } - - p_painter->setPen(oldPen); -} - -void VTextDocumentLayout::relayout() -{ - QTextDocument *doc = document(); - - // Update the margin. - m_margin = doc->documentMargin(); - - QTextBlock block = doc->lastBlock(); - while (block.isValid()) { - clearBlockLayout(block); - block = block.previous(); - } - - block = doc->firstBlock(); - while (block.isValid()) { - layoutBlock(block); - block = block.next(); - } - - updateDocumentSize(); - - emit update(QRectF(0., 0., 1000000000., 1000000000.)); -} - -void VTextDocumentLayout::relayout(const QSet &p_blocks) -{ - if (p_blocks.isEmpty()) { - return; - } - - QTextDocument *doc = document(); - - for (auto bn : p_blocks) { - QTextBlock block = doc->findBlockByNumber(bn); - if (block.isValid()) { - clearBlockLayout(block); - layoutBlock(block); - emit updateBlock(block); - } - } - - updateDocumentSize(); -} - -qreal VTextDocumentLayout::fetchInlineImagesForOneLine(const QVector &p_info, - const QTextLine *p_line, - qreal p_margin, - int &p_index, - QVector &p_images, - QVector> &p_imageRange) -{ - qreal maxHeight = 0; - int start = p_line->textStart(); - int end = p_line->textLength() + start; - - for (int i = 0; i < p_info.size(); ++i) { - const VPreviewedImageInfo &img = p_info[i]->m_imageInfo; - Q_ASSERT(img.m_inline); - - if (img.m_startPos >= start && img.m_startPos < end) { - // Start of a new image. - qreal startX = p_line->cursorToX(img.m_startPos) + p_margin; - qreal endX; - if (img.m_endPos <= end) { - // End an image. - endX = p_line->cursorToX(img.m_endPos) + p_margin; - p_images.append(&img); - p_imageRange.append(QPair(startX, endX)); - - QSize size = img.m_imageSize; - scaleSize(size, endX - startX, MAX_INLINE_IMAGE_HEIGHT); - if (size.height() > maxHeight) { - maxHeight = size.height(); - } - - // Image i has been drawn. - p_index = i + 1; - } else { - // This image cross the line. - endX = p_line->x() + p_line->width() + p_margin; - if (end - img.m_startPos >= ((img.m_endPos - img.m_startPos) >> 1)) { - // Put image at this side. - p_images.append(&img); - p_imageRange.append(QPair(startX, endX)); - - QSize size = img.m_imageSize; - scaleSize(size, endX - startX, MAX_INLINE_IMAGE_HEIGHT); - if (size.height() > maxHeight) { - maxHeight = size.height(); - } - - // Image i has been drawn. - p_index = i + 1; - } else { - // Just put a marker here. - p_images.append(NULL); - p_imageRange.append(QPair(startX, endX)); - } - - break; - } - } else if (img.m_endPos > start && img.m_startPos < start) { - qreal startX = p_line->x() + p_margin; - qreal endX = img.m_endPos > end ? p_line->x() + p_line->width() - : p_line->cursorToX(img.m_endPos); - if (p_index <= i) { - // Image i has not been drawn. Draw it here. - p_images.append(&img); - p_imageRange.append(QPair(startX, endX)); - - QSize size = img.m_imageSize; - scaleSize(size, endX - startX, MAX_INLINE_IMAGE_HEIGHT); - if (size.height() > maxHeight) { - maxHeight = size.height(); - } - - // Image i has been drawn. - p_index = i + 1; - } else { - // Image i has been drawn. Just put a marker here. - p_images.append(NULL); - p_imageRange.append(QPair(startX, endX)); - } - - if (img.m_endPos >= end) { - break; - } - } else if (img.m_endPos <= start) { - continue; - } else { - break; - } - } - - return maxHeight; -} - -int VTextDocumentLayout::getTextWidthWithinTextLine(const QTextLayout *p_layout, - int p_pos, - int p_length) -{ - QTextLine line = p_layout->lineForTextPosition(p_pos); - Q_ASSERT(line.isValid()); - Q_ASSERT(p_pos + p_length <= line.textStart() + line.textLength()); - return line.cursorToX(p_pos + p_length) - line.cursorToX(p_pos); -} - -void VTextDocumentLayout::updateBlockByNumber(int p_blockNumber) -{ - if (p_blockNumber == -1) { - return; - } - - QTextBlock block = document()->findBlockByNumber(p_blockNumber); - if (block.isValid()) { - emit updateBlock(block); - } -} diff --git a/src/vtextdocumentlayout.h b/src/vtextdocumentlayout.h deleted file mode 100644 index f0de9df7..00000000 --- a/src/vtextdocumentlayout.h +++ /dev/null @@ -1,374 +0,0 @@ -#ifndef VTEXTDOCUMENTLAYOUT_H -#define VTEXTDOCUMENTLAYOUT_H - -#include -#include -#include -#include -#include "vconstants.h" - -class VImageResourceManager2; -struct VPreviewedImageInfo; -struct VPreviewInfo; - - -class VTextDocumentLayout : public QAbstractTextDocumentLayout -{ - Q_OBJECT -public: - VTextDocumentLayout(QTextDocument *p_doc, - VImageResourceManager2 *p_imageMgr); - - void draw(QPainter *p_painter, const PaintContext &p_context) Q_DECL_OVERRIDE; - - int hitTest(const QPointF &p_point, Qt::HitTestAccuracy p_accuracy) const Q_DECL_OVERRIDE; - - int pageCount() const Q_DECL_OVERRIDE; - - QSizeF documentSize() const Q_DECL_OVERRIDE; - - QRectF frameBoundingRect(QTextFrame *p_frame) const Q_DECL_OVERRIDE; - - QRectF blockBoundingRect(const QTextBlock &p_block) const Q_DECL_OVERRIDE; - - void setCursorWidth(int p_width); - - int cursorWidth() const; - - void setLineLeading(qreal p_leading); - - qreal getLineLeading() const; - - // Return the block number which contains point @p_point. - // If @p_point is at the border, returns the block below. - int findBlockByPosition(const QPointF &p_point) const; - - void setImageWidthConstrainted(bool p_enabled); - - void setBlockImageEnabled(bool p_enabled); - - // Relayout all the blocks. - void relayout(); - - // Relayout @p_blocks. - void relayout(const QSet &p_blocks); - - void setImageLineColor(const QColor &p_color); - - void setCursorBlockMode(CursorBlock p_mode); - - void setVirtualCursorBlockWidth(int p_width); - - void clearLastCursorBlockWidth(); - - void setHighlightCursorLineBlockEnabled(bool p_enabled); - - void setCursorLineBlockBg(const QColor &p_bg); - - void setCursorLineBlockNumber(int p_blockNumber); - - // Request update block by block number. - void updateBlockByNumber(int p_blockNumber); - -signals: - // Emit to update current cursor block width if m_cursorBlockMode is enabled. - void cursorBlockWidthUpdated(int p_width); - -protected: - void documentChanged(int p_from, int p_charsRemoved, int p_charsAdded) Q_DECL_OVERRIDE; - -private: - // Denote the start and end position of a marker line. - struct Marker - { - QPointF m_start; - QPointF m_end; - }; - - struct ImagePaintInfo - { - // The rect to draw the image. - QRectF m_rect; - - // Name of the image. - QString m_name; - - bool isValid() - { - return !m_name.isEmpty(); - } - }; - - struct BlockInfo - { - BlockInfo() - { - reset(); - } - - void reset() - { - m_offset = -1; - m_rect = QRectF(); - m_markers.clear(); - m_images.clear(); - } - - bool hasOffset() const - { - return m_offset > -1 && !m_rect.isNull(); - } - - qreal top() const - { - Q_ASSERT(hasOffset()); - return m_offset; - } - - qreal bottom() const - { - Q_ASSERT(hasOffset()); - return m_offset + m_rect.height(); - } - - // Y offset of this block. - // -1 for invalid. - qreal m_offset; - - // The bounding rect of this block, including the margins. - // Null for invalid. - QRectF m_rect; - - // Markers to draw for this block. - // Y is the offset within this block. - QVector m_markers; - - // Images to draw for this block. - // Y is the offset within this block. - QVector m_images; - }; - - void layoutBlock(const QTextBlock &p_block); - - // Returns the total height of this block after layouting lines and inline - // images. - qreal layoutLines(const QTextBlock &p_block, - QTextLayout *p_tl, - QVector &p_markers, - QVector &p_images, - qreal p_availableWidth, - qreal p_height); - - // Layout inline image in a line. - // @p_info: if NULL, means just layout a marker. - // Returns the image height. - void layoutInlineImage(const VPreviewedImageInfo *p_info, - qreal p_heightInBlock, - qreal p_imageSpaceHeight, - qreal p_xStart, - qreal p_xEnd, - QVector &p_markers, - QVector &p_images); - - // Get inline images belonging to @p_line from @p_info. - // @p_index: image [0, p_index) has been drawn. - // @p_images: contains all images and markers (NULL element indicates it - // is just a placeholder for the marker. - // Returns the maximum height of the images. - qreal fetchInlineImagesForOneLine(const QVector &p_info, - const QTextLine *p_line, - qreal p_margin, - int &p_index, - QVector &p_images, - QVector> &p_imageRange); - - // Clear the layout of @p_block. - // Also clear all the offset behind this block. - void clearBlockLayout(QTextBlock &p_block); - - // Clear the offset of all the blocks from @p_blockNumber. - void clearOffsetFrom(int p_blockNumber); - - // Fill the offset filed from @p_blockNumber + 1. - void fillOffsetFrom(int p_blockNumber); - - // Update block count to @p_count due to document change. - // Maintain m_blocks. - // @p_changeStartBlock is the block number of the start block in this change. - void updateBlockCount(int p_count, int p_changeStartBlock); - - bool validateBlocks() const; - - void finishBlockLayout(const QTextBlock &p_block, - const QVector &p_markers, - const QVector &p_images); - - int previousValidBlockNumber(int p_number) const; - - int nextValidBlockNumber(int p_number) const; - - // Update block count and m_blocks size. - void updateDocumentSize(); - - QVector formatRangeFromSelection(const QTextBlock &p_block, - const QVector &p_selections) const; - - // Get the block range [first, last] by rect @p_rect. - // @p_rect: a clip region in document coordinates. If null, returns all the blocks. - // Return [-1, -1] if no valid block range found. - void blockRangeFromRect(const QRectF &p_rect, int &p_first, int &p_last) const; - - // Binary search to get the block range [first, last] by @p_rect. - void blockRangeFromRectBS(const QRectF &p_rect, int &p_first, int &p_last) const; - - // Return a rect from the layout. - // If @p_imageRect is not NULL and there is block image for this block, it will - // be set to the rect of that image. - // Return a null rect if @p_block has not been layouted. - QRectF blockRectFromTextLayout(const QTextBlock &p_block, - ImagePaintInfo *p_image = NULL); - - // Update document size when only block @p_blockNumber is changed and the height - // remain the same. - void updateDocumentSizeWithOneBlockChanged(int p_blockNumber); - - void adjustImagePaddingAndSize(const VPreviewedImageInfo *p_info, - int p_maximumWidth, - int &p_padding, - QSize &p_size) const; - - // Draw images of block @p_block. - // @p_offset: the offset for the drawing of the block. - void drawImages(QPainter *p_painter, - const QTextBlock &p_block, - const QPointF &p_offset); - - void drawMarkers(QPainter *p_painter, - const QTextBlock &p_block, - const QPointF &p_offset); - - void scaleSize(QSize &p_size, int p_width, int p_height); - - // Get text length in pixel. - // @p_pos: position within the layout. - int getTextWidthWithinTextLine(const QTextLayout *p_layout, int p_pos, int p_length); - - // Document margin on left/right/bottom. - qreal m_margin; - - // Maximum width of the contents. - qreal m_width; - - // The block number of the block which contains the m_width. - int m_maximumWidthBlockNumber; - - // Height of all the document (all the blocks). - qreal m_height; - - // Set the leading space of a line. - qreal m_lineLeading; - - // Block count of the document. - int m_blockCount; - - // Width of the cursor. - int m_cursorWidth; - - // Right margin for cursor. - qreal m_cursorMargin; - - QVector m_blocks; - - VImageResourceManager2 *m_imageMgr; - - bool m_blockImageEnabled; - - // Whether constraint the width of image to the width of the page. - bool m_imageWidthConstrainted; - - // Color of the image line. - QColor m_imageLineColor; - - // Draw cursor as block. - CursorBlock m_cursorBlockMode; - - // Virtual cursor block: cursor block on no character. - int m_virtualCursorBlockWidth; - - int m_lastCursorBlockWidth; - - // Whether highlight the block containing the cursor line. - bool m_highlightCursorLineBlock; - - // The cursor line's block background color. - QColor m_cursorLineBlockBg; - - // The block containing the cursor. - int m_cursorLineBlockNumber; -}; - -inline qreal VTextDocumentLayout::getLineLeading() const -{ - return m_lineLeading; -} - -inline void VTextDocumentLayout::setImageLineColor(const QColor &p_color) -{ - m_imageLineColor = p_color; -} - -inline void VTextDocumentLayout::scaleSize(QSize &p_size, int p_width, int p_height) -{ - if (p_size.width() > p_width || p_size.height() > p_height) { - p_size.scale(p_width, p_height, Qt::KeepAspectRatio); - } -} - -inline void VTextDocumentLayout::setCursorBlockMode(CursorBlock p_mode) -{ - m_cursorBlockMode = p_mode; -} - -inline void VTextDocumentLayout::setVirtualCursorBlockWidth(int p_width) -{ - m_virtualCursorBlockWidth = p_width; -} - -inline void VTextDocumentLayout::clearLastCursorBlockWidth() -{ - m_lastCursorBlockWidth = -1; -} - -inline void VTextDocumentLayout::setHighlightCursorLineBlockEnabled(bool p_enabled) -{ - if (m_highlightCursorLineBlock != p_enabled) { - m_highlightCursorLineBlock = p_enabled; - if (!m_highlightCursorLineBlock) { - int pre = m_cursorLineBlockNumber; - m_cursorLineBlockNumber = -1; - updateBlockByNumber(pre); - } - } -} - -inline void VTextDocumentLayout::setCursorLineBlockBg(const QColor &p_bg) -{ - if (p_bg != m_cursorLineBlockBg) { - m_cursorLineBlockBg = p_bg; - updateBlockByNumber(m_cursorLineBlockNumber); - } -} - -inline void VTextDocumentLayout::setCursorLineBlockNumber(int p_blockNumber) -{ - if (p_blockNumber != m_cursorLineBlockNumber) { - int pre = m_cursorLineBlockNumber; - m_cursorLineBlockNumber = p_blockNumber; - - if (m_highlightCursorLineBlock) { - updateBlockByNumber(pre); - updateBlockByNumber(m_cursorLineBlockNumber); - } - } -} -#endif // VTEXTDOCUMENTLAYOUT_H diff --git a/src/vtextedit.cpp b/src/vtextedit.cpp deleted file mode 100644 index c8004c07..00000000 --- a/src/vtextedit.cpp +++ /dev/null @@ -1,390 +0,0 @@ -#include "vtextedit.h" - -#include -#include -#include -#include - -#include "vtextdocumentlayout.h" -#include "vimageresourcemanager2.h" - -#define VIRTUAL_CURSOR_BLOCK_WIDTH 8 - -enum class BlockState -{ - Normal = 0, - CodeBlockStart, - CodeBlock, - CodeBlockEnd, - Comment -}; - - -VTextEdit::VTextEdit(QWidget *p_parent) - : QTextEdit(p_parent), - m_imageMgr(nullptr) -{ - init(); -} - -VTextEdit::VTextEdit(const QString &p_text, QWidget *p_parent) - : QTextEdit(p_text, p_parent), - m_imageMgr(nullptr) -{ - init(); -} - -VTextEdit::~VTextEdit() -{ - if (m_imageMgr) { - delete m_imageMgr; - } -} - -void VTextEdit::init() -{ - setAcceptRichText(false); - - m_lineNumberType = LineNumberType::None; - - m_blockImageEnabled = false; - - m_cursorBlockMode = CursorBlock::None; - - m_highlightCursorLineBlock = false; - - m_imageMgr = new VImageResourceManager2(); - - QTextDocument *doc = document(); - VTextDocumentLayout *docLayout = new VTextDocumentLayout(doc, m_imageMgr); - docLayout->setBlockImageEnabled(m_blockImageEnabled); - doc->setDocumentLayout(docLayout); - - docLayout->setVirtualCursorBlockWidth(VIRTUAL_CURSOR_BLOCK_WIDTH); - - connect(docLayout, &VTextDocumentLayout::cursorBlockWidthUpdated, - this, [this](int p_width) { - if (p_width != cursorWidth() - && p_width > VIRTUAL_CURSOR_BLOCK_WIDTH) { - setCursorWidth(p_width); - } - }); - - m_lineNumberArea = new VLineNumberArea(this, - document(), - fontMetrics().width(QLatin1Char('8')), - fontMetrics().height(), - this); - connect(doc, &QTextDocument::blockCountChanged, - this, &VTextEdit::updateLineNumberAreaMargin); - connect(this, &QTextEdit::textChanged, - this, &VTextEdit::updateLineNumberArea); - connect(verticalScrollBar(), &QScrollBar::valueChanged, - this, &VTextEdit::updateLineNumberArea); - connect(this, &QTextEdit::cursorPositionChanged, - this, [this]() { - if (m_highlightCursorLineBlock) { - QTextCursor cursor = textCursor(); - getLayout()->setCursorLineBlockNumber(cursor.block().blockNumber()); - } - - updateLineNumberArea(); - }); -} - -VTextDocumentLayout *VTextEdit::getLayout() const -{ - return qobject_cast(document()->documentLayout()); -} - -void VTextEdit::setLineLeading(qreal p_leading) -{ - getLayout()->setLineLeading(p_leading); -} - -void VTextEdit::resizeEvent(QResizeEvent *p_event) -{ - QTextEdit::resizeEvent(p_event); - - if (m_lineNumberType != LineNumberType::None) { - QRect rect = contentsRect(); - m_lineNumberArea->setGeometry(QRect(rect.left(), - rect.top(), - m_lineNumberArea->calculateWidth(), - rect.height())); - } -} - -void VTextEdit::paintLineNumberArea(QPaintEvent *p_event) -{ - if (m_lineNumberType == LineNumberType::None) { - updateLineNumberAreaMargin(); - m_lineNumberArea->hide(); - return; - } - - QPainter painter(m_lineNumberArea); - painter.fillRect(p_event->rect(), m_lineNumberArea->getBackgroundColor()); - - QTextBlock block = firstVisibleBlock(); - if (!block.isValid()) { - return; - } - - VTextDocumentLayout *layout = getLayout(); - Q_ASSERT(layout); - - int blockNumber = block.blockNumber(); - QRectF rect = layout->blockBoundingRect(block); - int top = contentOffsetY() + (int)rect.y(); - int bottom = top + (int)rect.height(); - int eventTop = p_event->rect().top(); - int eventBtm = p_event->rect().bottom(); - const int digitHeight = m_lineNumberArea->getDigitHeight(); - const int curBlockNumber = textCursor().block().blockNumber(); - painter.setPen(m_lineNumberArea->getForegroundColor()); - const int leading = (int)layout->getLineLeading(); - - // Display line number only in code block. - if (m_lineNumberType == LineNumberType::CodeBlock) { - int number = 0; - while (block.isValid() && top <= eventBtm) { - int blockState = block.userState(); - switch (blockState) { - case (int)BlockState::CodeBlockStart: - Q_ASSERT(number == 0); - number = 1; - break; - - case (int)BlockState::CodeBlockEnd: - number = 0; - break; - - case (int)BlockState::CodeBlock: - if (number == 0) { - // Need to find current line number in code block. - QTextBlock startBlock = block.previous(); - while (startBlock.isValid()) { - if (startBlock.userState() == (int)BlockState::CodeBlockStart) { - number = block.blockNumber() - startBlock.blockNumber(); - break; - } - - startBlock = startBlock.previous(); - } - } - - break; - - default: - break; - } - - if (blockState == (int)BlockState::CodeBlock) { - if (block.isVisible() && bottom >= eventTop) { - QString numberStr = QString::number(number); - painter.drawText(0, - top + leading, - m_lineNumberArea->width(), - digitHeight, - Qt::AlignRight, - numberStr); - } - - ++number; - } - - block = block.next(); - top = bottom; - bottom = top + (int)layout->blockBoundingRect(block).height(); - } - - return; - } - - // Handle m_lineNumberType 1 and 2. - Q_ASSERT(m_lineNumberType == LineNumberType::Absolute - || m_lineNumberType == LineNumberType::Relative); - while (block.isValid() && top <= eventBtm) { - if (block.isVisible() && bottom >= eventTop) { - bool currentLine = false; - int number = blockNumber + 1; - if (m_lineNumberType == LineNumberType::Relative) { - number = blockNumber - curBlockNumber; - if (number == 0) { - currentLine = true; - number = blockNumber + 1; - } else if (number < 0) { - number = -number; - } - } else if (blockNumber == curBlockNumber) { - currentLine = true; - } - - QString numberStr = QString::number(number); - - if (currentLine) { - QFont font = painter.font(); - font.setBold(true); - painter.setFont(font); - } - - painter.drawText(0, - top + leading, - m_lineNumberArea->width(), - digitHeight, - Qt::AlignRight, - numberStr); - - if (currentLine) { - QFont font = painter.font(); - font.setBold(false); - painter.setFont(font); - } - } - - block = block.next(); - top = bottom; - bottom = top + (int)layout->blockBoundingRect(block).height(); - ++blockNumber; - } -} - -void VTextEdit::updateLineNumberAreaMargin() -{ - int width = 0; - if (m_lineNumberType != LineNumberType::None) { - width = m_lineNumberArea->calculateWidth(); - } - - if (width != viewportMargins().left()) { - setViewportMargins(width, 0, 0, 0); - } -} - -void VTextEdit::updateLineNumberArea() -{ - if (m_lineNumberType != LineNumberType::None) { - if (!m_lineNumberArea->isVisible()) { - updateLineNumberAreaMargin(); - m_lineNumberArea->show(); - } - - m_lineNumberArea->update(); - } else if (m_lineNumberArea->isVisible()) { - updateLineNumberAreaMargin(); - m_lineNumberArea->hide(); - } -} - -QTextBlock VTextEdit::firstVisibleBlock() const -{ - VTextDocumentLayout *layout = getLayout(); - Q_ASSERT(layout); - int blockNumber = layout->findBlockByPosition(QPointF(0, -contentOffsetY())); - return document()->findBlockByNumber(blockNumber); -} - -int VTextEdit::contentOffsetY() const -{ - QScrollBar *sb = verticalScrollBar(); - return -(sb->value()); -} - -void VTextEdit::clearBlockImages() -{ - m_imageMgr->clear(); - - getLayout()->relayout(); -} - -void VTextEdit::relayout(const QSet &p_blocks) -{ - getLayout()->relayout(p_blocks); -} - -bool VTextEdit::containsImage(const QString &p_imageName) const -{ - return m_imageMgr->contains(p_imageName); -} - -QSize VTextEdit::imageSize(const QString &p_imageName) const -{ - const QPixmap *img = m_imageMgr->findImage(p_imageName); - if (img) { - return img->size(); - } - - return QSize(); -} - -void VTextEdit::addImage(const QString &p_imageName, const QPixmap &p_image) -{ - if (m_blockImageEnabled) { - m_imageMgr->addImage(p_imageName, p_image); - } -} - -void VTextEdit::removeImage(const QString &p_imageName) -{ - m_imageMgr->removeImage(p_imageName); -} - -void VTextEdit::setBlockImageEnabled(bool p_enabled) -{ - if (m_blockImageEnabled == p_enabled) { - return; - } - - m_blockImageEnabled = p_enabled; - - getLayout()->setBlockImageEnabled(m_blockImageEnabled); - - if (!m_blockImageEnabled) { - clearBlockImages(); - } -} - -void VTextEdit::setImageWidthConstrainted(bool p_enabled) -{ - getLayout()->setImageWidthConstrainted(p_enabled); -} - -void VTextEdit::setImageLineColor(const QColor &p_color) -{ - getLayout()->setImageLineColor(p_color); -} - -void VTextEdit::setCursorBlockMode(CursorBlock p_mode) -{ - if (p_mode != m_cursorBlockMode) { - m_cursorBlockMode = p_mode; - getLayout()->setCursorBlockMode(m_cursorBlockMode); - getLayout()->clearLastCursorBlockWidth(); - setCursorWidth(m_cursorBlockMode != CursorBlock::None ? VIRTUAL_CURSOR_BLOCK_WIDTH - : 1); - } -} - -void VTextEdit::setHighlightCursorLineBlockEnabled(bool p_enabled) -{ - if (m_highlightCursorLineBlock != p_enabled) { - auto layout = getLayout(); - m_highlightCursorLineBlock = p_enabled; - layout->setHighlightCursorLineBlockEnabled(p_enabled); - if (m_highlightCursorLineBlock) { - QTextCursor cursor = textCursor(); - layout->setCursorLineBlockNumber(cursor.block().blockNumber()); - } - } -} - -void VTextEdit::setCursorLineBlockBg(const QColor &p_bg) -{ - getLayout()->setCursorLineBlockBg(p_bg); -} - -void VTextEdit::relayout() -{ - getLayout()->relayout(); -} diff --git a/src/vtextedit.h b/src/vtextedit.h deleted file mode 100644 index e34ed263..00000000 --- a/src/vtextedit.h +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef VTEXTEDIT_H -#define VTEXTEDIT_H - -#include -#include - -#include "vlinenumberarea.h" -#include "vconstants.h" - -class VTextDocumentLayout; -class QPainter; -class QResizeEvent; -class VImageResourceManager2; - - -class VTextEdit : public QTextEdit, public VTextEditWithLineNumber -{ - Q_OBJECT -public: - explicit VTextEdit(QWidget *p_parent = nullptr); - - explicit VTextEdit(const QString &p_text, QWidget *p_parent = nullptr); - - virtual ~VTextEdit(); - - void init(); - - void setLineLeading(qreal p_leading); - - void paintLineNumberArea(QPaintEvent *p_event) Q_DECL_OVERRIDE; - - void setLineNumberType(LineNumberType p_type); - - void setLineNumberColor(const QColor &p_foreground, const QColor &p_background); - - QTextBlock firstVisibleBlock() const; - - void clearBlockImages(); - - // Whether the resoruce manager contains image of name @p_imageName. - bool containsImage(const QString &p_imageName) const; - - // Get the image size from the resource manager. - QSize imageSize(const QString &p_imageName) const; - - // Add an image to the resources. - void addImage(const QString &p_imageName, const QPixmap &p_image); - - // Remove an image from the resources. - void removeImage(const QString &p_imageName); - - void setBlockImageEnabled(bool p_enabled); - - void setImageWidthConstrainted(bool p_enabled); - - void setImageLineColor(const QColor &p_color); - - void relayout(const QSet &p_blocks); - - void setCursorBlockMode(CursorBlock p_mode); - - void setHighlightCursorLineBlockEnabled(bool p_enabled); - - void setCursorLineBlockBg(const QColor &p_bg); - - void relayout(); - -protected: - void resizeEvent(QResizeEvent *p_event) Q_DECL_OVERRIDE; - - // Return the Y offset of the content via the scrollbar. - int contentOffsetY() const; - -private slots: - // Update viewport margin to hold the line number area. - void updateLineNumberAreaMargin(); - - void updateLineNumberArea(); - -private: - VTextDocumentLayout *getLayout() const; - - VLineNumberArea *m_lineNumberArea; - - LineNumberType m_lineNumberType; - - VImageResourceManager2 *m_imageMgr; - - bool m_blockImageEnabled; - - CursorBlock m_cursorBlockMode; - - bool m_highlightCursorLineBlock; -}; - -inline void VTextEdit::setLineNumberType(LineNumberType p_type) -{ - if (p_type == m_lineNumberType) { - return; - } - - m_lineNumberType = p_type; - - updateLineNumberArea(); -} - -inline void VTextEdit::setLineNumberColor(const QColor &p_foreground, - const QColor &p_background) -{ - m_lineNumberArea->setForegroundColor(p_foreground); - m_lineNumberArea->setBackgroundColor(p_background); -} -#endif // VTEXTEDIT_H diff --git a/src/vtoolbox.cpp b/src/vtoolbox.cpp deleted file mode 100644 index b4102a1b..00000000 --- a/src/vtoolbox.cpp +++ /dev/null @@ -1,186 +0,0 @@ -#include "vtoolbox.h" - -#include -#include -#include -#include -#include -#include - -#include "vnote.h" -#include "utils/vutils.h" -#include "utils/viconutils.h" - -extern VNote *g_vnote; - -VToolBox::VToolBox(QWidget *p_parent) - : QWidget(p_parent), - m_currentIndex(-1) -{ - setupUI(); -} - -void VToolBox::setupUI() -{ - m_btnLayout = new QHBoxLayout(); - m_btnLayout->addStretch(); - m_btnLayout->setContentsMargins(0, 0, 0, 2); - m_btnLayout->setSpacing(0); - QWidget *wid = new QWidget(); - wid->setProperty("ToolBoxTitle", true); - wid->setLayout(m_btnLayout); - - m_widgetLayout = new QStackedLayout(); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(wid); - mainLayout->addLayout(m_widgetLayout); - mainLayout->setContentsMargins(0, 0, 0, 0); - - setLayout(mainLayout); -} - -int VToolBox::addItem(QWidget *p_widget, const QString &p_iconFile, const QString &p_text) -{ - int idx = m_items.size(); - - // New a button. - QIcon icon = VIconUtils::toolBoxIcon(p_iconFile); - QPushButton *btn = new QPushButton(icon, ""); - btn->setToolTip(p_text); - btn->setProperty("FlatBtn", true); - connect(btn, &QPushButton::clicked, - this, [this]() { - QObject *btn = sender(); - for (int i = 0; i < m_items.size(); ++i) { - if (m_items[i].m_btn == btn) { - setCurrentIndex(i); - break; - } - } - }); - - m_btnLayout->insertWidget(idx, btn); - - // Insert widget to layout. - m_widgetLayout->insertWidget(idx, p_widget); - - m_items.push_back(ItemInfo(p_widget, - p_text, - btn, - icon, - VIconUtils::toolBoxActiveIcon(p_iconFile))); - - if (m_items.size() == 1) { - setCurrentIndex(0); - } - - return idx; -} - -void VToolBox::setCurrentIndex(int p_idx) -{ - if (p_idx < 0 || p_idx >= m_items.size()) { - m_currentIndex = -1; - } else { - m_currentIndex = p_idx; - } - - setCurrentButtonIndex(m_currentIndex); - - m_widgetLayout->setCurrentIndex(m_currentIndex); - - QWidget *widget = m_widgetLayout->widget(m_currentIndex); - if (widget) { - widget->setFocus(); - } -} - -void VToolBox::setCurrentWidget(QWidget *p_widget) -{ - int idx = -1; - for (int i = 0; i < m_items.size(); ++i) { - if (m_items[i].m_widget == p_widget) { - idx = i; - break; - } - } - - setCurrentIndex(idx); -} - -void VToolBox::setCurrentButtonIndex(int p_idx) -{ - // Remove the text of all button. - for (int i = 0; i < m_items.size(); ++i) { - QPushButton *btn = m_items[i].m_btn; - btn->setText(""); - btn->setIcon(m_items[i].m_icon); - btn->clearFocus(); - VUtils::setDynamicProperty(btn, "ToolBoxActiveBtn", false); - } - - if (p_idx < 0 || p_idx >= m_items.size()) { - return; - } - - QPushButton *curBtn = m_items[p_idx].m_btn; - curBtn->setText(m_items[p_idx].m_text); - curBtn->setIcon(m_items[p_idx].m_activeIcon); - VUtils::setDynamicProperty(curBtn, "ToolBoxActiveBtn", true); -} - -void VToolBox::showNavigation() -{ - clearNavigation(); - - if (!isVisible()) { - return; - } - - for (int i = 0; i < 26 && i < m_items.size(); ++i) { - const ItemInfo &item = m_items[i]; - - QChar key('a' + i); - m_keyMap[key] = item.m_widget; - - QString str = QString(m_majorKey) + key; - QLabel *label = new QLabel(str, this); - label->setStyleSheet(g_vnote->getNavigationLabelStyle(str)); - label->show(); - QRect rect = item.m_btn->geometry(); - // Display the label at the end to show the file name. - label->move(rect.x(), rect.y() + rect.height() / 2); - m_naviLabels.append(label); - } -} - -bool VToolBox::handleKeyNavigation(int p_key, bool &p_succeed) -{ - static bool secondKey = false; - bool ret = false; - p_succeed = false; - QChar keyChar = VUtils::keyToChar(p_key); - if (secondKey && !keyChar.isNull()) { - secondKey = false; - p_succeed = true; - ret = true; - auto it = m_keyMap.find(keyChar); - if (it != m_keyMap.end()) { - QWidget *widget = static_cast(it.value()); - setCurrentWidget(widget); - } - } else if (keyChar == m_majorKey) { - // Major key pressed. - // Need second key if m_keyMap is not empty. - if (m_keyMap.isEmpty()) { - p_succeed = true; - } else { - secondKey = true; - } - - ret = true; - } - - return ret; -} diff --git a/src/vtoolbox.h b/src/vtoolbox.h deleted file mode 100644 index bb6462d3..00000000 --- a/src/vtoolbox.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef VTOOLBOX_H -#define VTOOLBOX_H - -#include -#include -#include -#include - -#include "vnavigationmode.h" - -class QPushButton; -class QStackedLayout; -class QBoxLayout; - -class VToolBox : public QWidget, public VNavigationMode -{ - Q_OBJECT -public: - explicit VToolBox(QWidget *p_parent = nullptr); - - int addItem(QWidget *p_widget, const QString &p_iconFile, const QString &p_text); - - void setCurrentIndex(int p_idx); - - void setCurrentWidget(QWidget *p_widget); - - // Implementations for VNavigationMode. - void showNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - -private: - struct ItemInfo - { - ItemInfo() - : m_widget(nullptr), m_btn(nullptr) - { - } - - ItemInfo(QWidget *p_widget, - const QString &p_text, - QPushButton *p_btn, - const QIcon &p_icon, - const QIcon &p_activeIcon) - : m_widget(p_widget), - m_text(p_text), - m_btn(p_btn), - m_icon(p_icon), - m_activeIcon(p_activeIcon) - { - } - - QWidget *m_widget; - QString m_text; - - QPushButton *m_btn; - QIcon m_icon; - QIcon m_activeIcon; - }; - - void setupUI(); - - void setCurrentButtonIndex(int p_idx); - - QBoxLayout *m_btnLayout; - - QStackedLayout *m_widgetLayout; - - int m_currentIndex; - - QVector m_items; -}; - -#endif // VTOOLBOX_H diff --git a/src/vvimindicator.cpp b/src/vvimindicator.cpp deleted file mode 100644 index eed512c6..00000000 --- a/src/vvimindicator.cpp +++ /dev/null @@ -1,565 +0,0 @@ -#include "vvimindicator.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vconfigmanager.h" -#include "vbuttonwithwidget.h" -#include "vedittab.h" -#include "vpalette.h" - -extern VConfigManager *g_config; - -extern VPalette *g_palette; - -VVimIndicator::VVimIndicator(QWidget *p_parent) - : QWidget(p_parent), m_vim(NULL) -{ - setupUI(); -} - -void VVimIndicator::setupUI() -{ - m_cmdLineEdit = new VVimCmdLineEdit(this); - m_cmdLineEdit->setProperty("VimCommandLine", true); - connect(m_cmdLineEdit, &VVimCmdLineEdit::commandCancelled, - this, [this](){ - if (m_editTab) { - m_editTab->focusTab(); - } - - // NOTICE: m_cmdLineEdit should not hide itself before setting - // focus to edit tab. - m_cmdLineEdit->hide(); - - if (m_vim) { - m_vim->processCommandLineCancelled(); - } - }); - - connect(m_cmdLineEdit, &VVimCmdLineEdit::commandFinished, - this, [this](VVim::CommandLineType p_type, const QString &p_cmd){ - if (m_editTab) { - m_editTab->focusTab(); - } - - m_cmdLineEdit->hide(); - - // Hide the cmd line edit before execute the command. - // If we execute the command first, we will get Chinese input - // method enabled after returning to read mode. - if (m_vim) { - m_vim->processCommandLine(p_type, p_cmd); - } - }); - - connect(m_cmdLineEdit, &VVimCmdLineEdit::commandChanged, - this, [this](VVim::CommandLineType p_type, const QString &p_cmd){ - if (m_vim) { - m_vim->processCommandLineChanged(p_type, p_cmd); - } - }); - - connect(m_cmdLineEdit, &VVimCmdLineEdit::requestNextCommand, - this, [this](VVim::CommandLineType p_type, const QString &p_cmd){ - if (m_vim) { - QString cmd = m_vim->getNextCommandHistory(p_type, p_cmd); - if (!cmd.isNull()) { - m_cmdLineEdit->setCommand(cmd); - } else { - m_cmdLineEdit->restoreUserLastInput(); - } - } - }); - - connect(m_cmdLineEdit, &VVimCmdLineEdit::requestPreviousCommand, - this, [this](VVim::CommandLineType p_type, const QString &p_cmd){ - if (m_vim) { - QString cmd = m_vim->getPreviousCommandHistory(p_type, p_cmd); - if (!cmd.isNull()) { - m_cmdLineEdit->setCommand(cmd); - } - } - }); - - connect(m_cmdLineEdit, &VVimCmdLineEdit::requestRegister, - this, [this](int p_key, int p_modifiers){ - if (m_vim) { - QString val = m_vim->readRegister(p_key, p_modifiers); - if (!val.isEmpty()) { - m_cmdLineEdit->setText(m_cmdLineEdit->text() + val); - } - } - }); - - m_cmdLineEdit->hide(); - - m_modeLabel = new QLabel(this); - m_modeLabel->setProperty("VimIndicatorModeLabel", true); - - QTreeWidget *regTree = new QTreeWidget(this); - regTree->setProperty("ItemBorder", true); - regTree->setRootIsDecorated(false); - regTree->setColumnCount(2); - regTree->header()->setStretchLastSection(true); - QStringList headers; - headers << tr("Register") << tr("Value"); - regTree->setHeaderLabels(headers); - - m_regBtn = new VButtonWithWidget("\"", - regTree, - this); - m_regBtn->setToolTip(tr("Registers")); - m_regBtn->setProperty("StatusBtn", true); - m_regBtn->setFocusPolicy(Qt::NoFocus); - connect(m_regBtn, &VButtonWithWidget::popupWidgetAboutToShow, - this, &VVimIndicator::updateRegistersTree); - - QTreeWidget *markTree = new QTreeWidget(this); - markTree->setProperty("ItemBorder", true); - markTree->setRootIsDecorated(false); - markTree->setColumnCount(4); - markTree->header()->setStretchLastSection(true); - headers.clear(); - headers << tr("Mark") << tr("Line") << tr("Column") << tr("Text"); - markTree->setHeaderLabels(headers); - - m_markBtn = new VButtonWithWidget("[]", - markTree, - this); - m_markBtn->setToolTip(tr("Marks")); - m_markBtn->setProperty("StatusBtn", true); - m_markBtn->setFocusPolicy(Qt::NoFocus); - connect(m_markBtn, &VButtonWithWidget::popupWidgetAboutToShow, - this, &VVimIndicator::updateMarksTree); - - m_keyLabel = new QLabel(this); - m_keyLabel->setProperty("VimIndicatorKeyLabel", true); - QFontMetrics metric(font()); - m_keyLabel->setMinimumWidth(metric.width('A') * 5); - - QHBoxLayout *mainLayout = new QHBoxLayout(this); - mainLayout->addStretch(); - mainLayout->addWidget(m_cmdLineEdit); - mainLayout->addWidget(m_modeLabel); - mainLayout->addWidget(m_regBtn); - mainLayout->addWidget(m_markBtn); - mainLayout->addWidget(m_keyLabel); - mainLayout->setContentsMargins(0, 0, 0, 0); - - setLayout(mainLayout); -} - -QString VVimIndicator::modeToString(VimMode p_mode) const -{ - QString str; - - switch (p_mode) { - case VimMode::Normal: - str = tr("Normal"); - break; - - case VimMode::Insert: - str = tr("Insert"); - break; - - case VimMode::Visual: - str = tr("Visual"); - break; - - case VimMode::VisualLine: - str = tr("VisualLine"); - break; - - case VimMode::Replace: - str = tr("Replace"); - break; - - default: - str = tr("Unknown"); - break; - } - - return str; -} - -static QString modeBackgroundColor(VimMode p_mode) -{ - QString color; - - switch (p_mode) { - case VimMode::Normal: - color = g_config->getEditorVimNormalBg(); - break; - - case VimMode::Insert: - color = g_config->getEditorVimInsertBg(); - break; - - case VimMode::Visual: - color = g_config->getEditorVimVisualBg(); - break; - - case VimMode::VisualLine: - color = g_config->getEditorVimVisualBg(); - break; - - case VimMode::Replace: - color = g_config->getEditorVimReplaceBg(); - break; - - default: - color = "red"; - break; - } - - return color; -} - -static void fillTreeItemsWithRegisters(QTreeWidget *p_tree, - const QMap &p_regs) -{ - p_tree->clear(); - for (auto const ® : p_regs) { - if (reg.m_value.isEmpty()) { - continue; - } - - QStringList itemStr; - itemStr << reg.m_name << reg.m_value; - QTreeWidgetItem *item = new QTreeWidgetItem(p_tree, itemStr); - item->setFlags(item->flags() | Qt::ItemIsSelectable | Qt::ItemIsEditable); - } - - p_tree->resizeColumnToContents(0); - p_tree->resizeColumnToContents(1); -} - -void VVimIndicator::update(const VVim *p_vim, const VEditTab *p_editTab) -{ - m_editTab = const_cast(p_editTab); - if (m_vim != p_vim) { - // Disconnect from previous Vim. - if (m_vim) { - disconnect(m_vim.data(), 0, this, 0); - } - - m_vim = const_cast(p_vim); - if (m_vim) { - // Connect signal. - connect(m_vim.data(), &VVim::commandLineTriggered, - this, &VVimIndicator::triggerCommandLine); - - m_cmdLineEdit->hide(); - } - } - - if (!m_vim) { - m_cmdLineEdit->hide(); - return; - } - - VimMode mode = VimMode::Normal; - QChar curRegName(' '); - QChar lastUsedMark; - QString pendingKeys; - if (p_vim) { - mode = p_vim->getMode(); - curRegName = p_vim->getCurrentRegisterName(); - lastUsedMark = p_vim->getMarks().getLastUsedMark(); - pendingKeys = p_vim->getPendingKeys(); - } - - m_modeLabel->setStyleSheet(QString("background: %1;").arg(modeBackgroundColor(mode))); - m_modeLabel->setText(modeToString(mode)); - - m_regBtn->setText(curRegName); - - QString markText = QString("[%1]") - .arg(lastUsedMark.isNull() ? QChar(' ') : lastUsedMark); - m_markBtn->setText(markText); - - m_keyLabel->setText(pendingKeys); -} - -void VVimIndicator::updateRegistersTree(QWidget *p_widget) -{ - QTreeWidget *regTree = dynamic_cast(p_widget); - if (!m_vim) { - regTree->clear(); - return; - } - - const QMap ®s = m_vim->getRegisters(); - fillTreeItemsWithRegisters(regTree, regs); -} - -static void fillTreeItemsWithMarks(QTreeWidget *p_tree, - const QMap &p_marks) -{ - p_tree->clear(); - for (auto const &mark : p_marks) { - if (!mark.m_location.isValid()) { - continue; - } - - QStringList itemStr; - itemStr << mark.m_name << QString::number(mark.m_location.m_blockNumber + 1) - << QString::number(mark.m_location.m_positionInBlock) << mark.m_text; - QTreeWidgetItem *item = new QTreeWidgetItem(p_tree, itemStr); - item->setFlags(item->flags() | Qt::ItemIsSelectable | Qt::ItemIsEditable); - } - - p_tree->resizeColumnToContents(0); - p_tree->resizeColumnToContents(1); - p_tree->resizeColumnToContents(2); - p_tree->resizeColumnToContents(3); -} - -void VVimIndicator::updateMarksTree(QWidget *p_widget) -{ - QTreeWidget *markTree = dynamic_cast(p_widget); - if (!m_vim) { - markTree->clear(); - return; - } - - const QMap &marks = m_vim->getMarks().getMarks(); - fillTreeItemsWithMarks(markTree, marks); -} - -void VVimIndicator::triggerCommandLine(VVim::CommandLineType p_type) -{ - m_cmdLineEdit->reset(p_type); -} - -VVimCmdLineEdit::VVimCmdLineEdit(QWidget *p_parent) - : QLineEdit(p_parent), m_type(VVim::CommandLineType::Invalid), - m_registerPending(false), m_enableInputMethod(true) -{ - // When user delete all the text, cancel command input. - connect(this, &VVimCmdLineEdit::textChanged, - this, [this](const QString &p_text){ - if (p_text.isEmpty()) { - emit commandCancelled(); - } else { - emit commandChanged(m_type, p_text.right(p_text.size() - 1)); - } - }); - - connect(this, &VVimCmdLineEdit::textEdited, - this, [this](const QString &p_text){ - if (p_text.size() < 2) { - m_userLastInput.clear(); - } else { - m_userLastInput = p_text.right(p_text.size() - 1); - } - }); - - m_originStyleSheet = styleSheet(); -} - -QString VVimCmdLineEdit::getCommand() const -{ - QString tx = text(); - if (tx.size() < 2) { - return ""; - } else { - return tx.right(tx.size() - 1); - } -} - -QString VVimCmdLineEdit::commandLineTypeLeader(VVim::CommandLineType p_type) -{ - QString leader; - switch (p_type) { - case VVim::CommandLineType::Command: - leader = ":"; - break; - - case VVim::CommandLineType::SearchForward: - leader = "/"; - break; - - case VVim::CommandLineType::SearchBackward: - leader = "?"; - break; - - case VVim::CommandLineType::Invalid: - leader.clear(); - break; - - default: - Q_ASSERT(false); - break; - } - - return leader; -} - -void VVimCmdLineEdit::reset(VVim::CommandLineType p_type) -{ - m_type = p_type; - m_userLastInput.clear(); - setCommand(""); - show(); - setFocus(); - setInputMethodEnabled(p_type != VVim::CommandLineType::Command); -} - -void VVimCmdLineEdit::setInputMethodEnabled(bool p_enabled) -{ - if (m_enableInputMethod != p_enabled) { - m_enableInputMethod = p_enabled; - - QInputMethod *im = QGuiApplication::inputMethod(); - im->reset(); - // Ask input method to query current state, which will call inputMethodQuery(). - im->update(Qt::ImEnabled); - } -} - -QVariant VVimCmdLineEdit::inputMethodQuery(Qt::InputMethodQuery p_query) const -{ - if (p_query == Qt::ImEnabled) { - return m_enableInputMethod; - } - - return QLineEdit::inputMethodQuery(p_query); -} - -// See if @p_modifiers is Control which is different on macOs and Windows. -static bool isControlModifier(int p_modifiers) -{ -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - return p_modifiers == Qt::MetaModifier; -#else - return p_modifiers == Qt::ControlModifier; -#endif -} - -void VVimCmdLineEdit::keyPressEvent(QKeyEvent *p_event) -{ - int key = p_event->key(); - int modifiers = p_event->modifiers(); - - if (m_registerPending) { - // Ctrl and Shift may be sent out first. - if (key == Qt::Key_Control || key == Qt::Key_Shift || key == Qt::Key_Meta) { - goto exit; - } - - // Expecting a register name. - emit requestRegister(key, modifiers); - - p_event->accept(); - setRegisterPending(false); - return; - } - - if ((key == Qt::Key_Return && modifiers == Qt::NoModifier) - || (key == Qt::Key_Enter && modifiers == Qt::KeypadModifier)) { - // Enter, complete the command line input. - p_event->accept(); - emit commandFinished(m_type, getCommand()); - return; - } else if (key == Qt::Key_Escape - || (key == Qt::Key_BracketLeft && isControlModifier(modifiers))) { - // Exit command line input. - setText(commandLineTypeLeader(m_type)); - p_event->accept(); - emit commandCancelled(); - return; - } - - switch (key) { - case Qt::Key_U: - if (isControlModifier(modifiers)) { - // Ctrl+U, delete all user input. - setText(commandLineTypeLeader(m_type)); - p_event->accept(); - return; - } - - break; - - case Qt::Key_N: - if (!isControlModifier(modifiers)) { - break; - } - // Ctrl+N, request next command. - // Fall through. - case Qt::Key_Down: - { - emit requestNextCommand(m_type, getCommand()); - p_event->accept(); - return; - } - - case Qt::Key_P: - if (!isControlModifier(modifiers)) { - break; - } - // Ctrl+P, request previous command. - // Fall through. - case Qt::Key_Up: - { - emit requestPreviousCommand(m_type, getCommand()); - p_event->accept(); - return; - } - - case Qt::Key_R: - { - if (isControlModifier(modifiers)) { - // Ctrl+R, insert the content of a register. - setRegisterPending(true); - p_event->accept(); - return; - } - } - - default: - break; - } - -exit: - QLineEdit::keyPressEvent(p_event); -} - -void VVimCmdLineEdit::focusOutEvent(QFocusEvent *p_event) -{ - if (p_event->reason() != Qt::ActiveWindowFocusReason) { - emit commandCancelled(); - } -} - -void VVimCmdLineEdit::setCommand(const QString &p_cmd) -{ - setText(commandLineTypeLeader(m_type) + p_cmd); -} - -void VVimCmdLineEdit::restoreUserLastInput() -{ - setCommand(m_userLastInput); -} - -void VVimCmdLineEdit::setRegisterPending(bool p_pending) -{ - if (p_pending && !m_registerPending) { - // Going to pending. - setStyleSheet(QString("background: %1;").arg(g_palette->color("vim_indicator_cmd_edit_pending_bg"))); - } else if (!p_pending && m_registerPending) { - // Leaving pending. - setStyleSheet(m_originStyleSheet); - } - - m_registerPending = p_pending; -} diff --git a/src/vvimindicator.h b/src/vvimindicator.h deleted file mode 100644 index 74b1ea55..00000000 --- a/src/vvimindicator.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef VVIMINDICATOR_H -#define VVIMINDICATOR_H - -#include -#include -#include -#include "utils/vvim.h" - -class QLabel; -class VButtonWithWidget; -class QKeyEvent; -class QFocusEvent; -class VEditTab; - -class VVimCmdLineEdit : public QLineEdit -{ - Q_OBJECT - -public: - explicit VVimCmdLineEdit(QWidget *p_parent = 0); - - void reset(VVim::CommandLineType p_type); - - // Set the command to @p_cmd with leader unchanged. - void setCommand(const QString &p_cmd); - - // Get the command. - QString getCommand() const; - - void restoreUserLastInput(); - - QVariant inputMethodQuery(Qt::InputMethodQuery p_query) const Q_DECL_OVERRIDE; - -signals: - // User has finished the input and the command is ready to execute. - void commandFinished(VVim::CommandLineType p_type, const QString &p_cmd); - - // User cancelled the input. - void commandCancelled(); - - // User request the next command in the history. - void requestNextCommand(VVim::CommandLineType p_type, const QString &p_cmd); - - // User request the previous command in the history. - void requestPreviousCommand(VVim::CommandLineType p_type, const QString &p_cmd); - - // Emit when the input text changed. - void commandChanged(VVim::CommandLineType p_type, const QString &p_cmd); - - // Emit when expecting to read a register. - void requestRegister(int p_key, int p_modifiers); - -protected: - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - - void focusOutEvent(QFocusEvent *p_event) Q_DECL_OVERRIDE; - -private: - // Return the leader of @p_type. - QString commandLineTypeLeader(VVim::CommandLineType p_type); - - void setRegisterPending(bool p_pending); - - void setInputMethodEnabled(bool p_enabled); - - VVim::CommandLineType m_type; - - // The latest command user input. - QString m_userLastInput; - - // Whether we are expecting a register name to read. - bool m_registerPending; - - QString m_originStyleSheet; - - // Whether enable input method. - bool m_enableInputMethod; -}; - -class VVimIndicator : public QWidget -{ - Q_OBJECT - -public: - explicit VVimIndicator(QWidget *p_parent = 0); - - // Update indicator according to @p_vim. - void update(const VVim *p_vim, const VEditTab *p_editTab); - -private slots: - void updateRegistersTree(QWidget *p_widget); - - void updateMarksTree(QWidget *p_widget); - - // Vim request to trigger command line. - void triggerCommandLine(VVim::CommandLineType p_type); - -private: - void setupUI(); - - QString modeToString(VimMode p_mode) const; - - // Command line input. - VVimCmdLineEdit *m_cmdLineEdit; - - // Indicate the mode. - QLabel *m_modeLabel; - - // Indicate the registers. - VButtonWithWidget *m_regBtn; - - // Indicate the marks. - VButtonWithWidget *m_markBtn; - - // Indicate the pending keys. - QLabel *m_keyLabel; - - QPointer m_vim; - QPointer m_editTab; -}; - -#endif // VVIMINDICATOR_H diff --git a/src/vwebview.cpp b/src/vwebview.cpp deleted file mode 100644 index 0152207d..00000000 --- a/src/vwebview.cpp +++ /dev/null @@ -1,147 +0,0 @@ -#include "vwebview.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "vfile.h" -#include "utils/vclipboardutils.h" -#include "utils/viconutils.h" - -// We set the property of the clipboard to mark that the URL copied in the -// clipboard has been altered. -static const QString c_ClipboardPropertyMark = "CopiedImageURLAltered"; - -VWebView::VWebView(VFile *p_file, QWidget *p_parent) - : QWebEngineView(p_parent), m_file(p_file), m_actionHooked(false) -{ - setAcceptDrops(false); -} - -void VWebView::contextMenuEvent(QContextMenuEvent *p_event) -{ -#if defined(Q_OS_WIN) - if (!m_actionHooked) { - m_actionHooked = true; - - // "Copy Image URL" action will put the encoded URL to the clipboard as text - // and the URL as URLs. If the URL contains Chinese, OneNote or Word could not - // recognize it. - // We need to change it to only-space-encoded text. - QAction *copyImageUrlAct = pageAction(QWebEnginePage::CopyImageUrlToClipboard); - connect(copyImageUrlAct, &QAction::triggered, - this, [this](){ - // To avoid failure of setting clipboard mime data. - QCoreApplication::processEvents(); - - QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - clipboard->setProperty(c_ClipboardPropertyMark.toLatin1(), false); - if (clipboard->ownsClipboard() - && mimeData->hasText() - && mimeData->hasUrls()) { - QString text = mimeData->text(); - QList urls = mimeData->urls(); - if (urls.size() == 1 - && urls[0].isLocalFile() - && urls[0].toEncoded() == text) { - QString spaceOnlyText = urls[0].toString(QUrl::EncodeSpaces); - if (spaceOnlyText != text) { - // Set new mime data. - QMimeData *data = new QMimeData(); - data->setUrls(urls); - data->setText(spaceOnlyText); - clipboard->setMimeData(data); - - clipboard->setProperty(c_ClipboardPropertyMark.toLatin1(), true); - qDebug() << "clipboard copy image URL altered" << spaceOnlyText; - } - } - } - }); - } -#endif - - QMenu *menu = page()->createStandardContextMenu(); - menu->setToolTipsVisible(true); - - const QList actions = menu->actions(); - - if (!hasSelection() && m_file && m_file->isModifiable()) { - QAction *editAct= new QAction(VIconUtils::menuIcon(":/resources/icons/edit_note.svg"), - tr("&Edit"), menu); - editAct->setToolTip(tr("Edit current note")); - connect(editAct, &QAction::triggered, - this, &VWebView::handleEditAction); - menu->insertAction(actions.isEmpty() ? NULL : actions[0], editAct); - // actions does not contain editAction. - if (!actions.isEmpty()) { - menu->insertSeparator(actions[0]); - } - } - - // We need to replace the "Copy Image" action, because the default one use - // the fully-encoded URL to fetch the image while Windows seems to not - // recognize it. -#if defined(Q_OS_WIN) - QAction *defaultCopyImageAct = pageAction(QWebEnginePage::CopyImageToClipboard); - if (defaultCopyImageAct && actions.contains(defaultCopyImageAct)) { - QAction *copyImageAct = new QAction(defaultCopyImageAct->text(), menu); - copyImageAct->setToolTip(defaultCopyImageAct->toolTip()); - connect(copyImageAct, &QAction::triggered, - this, &VWebView::copyImage); - menu->insertAction(defaultCopyImageAct, copyImageAct); - menu->removeAction(defaultCopyImageAct); - } -#endif - - menu->exec(p_event->globalPos()); - delete menu; -} - -void VWebView::handleEditAction() -{ - emit editNote(); -} - -void VWebView::copyImage() -{ - Q_ASSERT(m_actionHooked); - - // triggerPageAction(QWebEnginePage::CopyImageUrlToClipboard) will not really - // trigger the corresponding action. It just do the stuff directly. - QAction *copyImageUrlAct = pageAction(QWebEnginePage::CopyImageUrlToClipboard); - copyImageUrlAct->trigger(); - - QCoreApplication::processEvents(); - - QClipboard *clipboard = QApplication::clipboard(); - if (clipboard->property(c_ClipboardPropertyMark.toLatin1()).toBool()) { - const QMimeData *mimeData = clipboard->mimeData(); - QString imgPath; - if (mimeData->hasUrls()) { - QList urls = mimeData->urls(); - if (urls[0].isLocalFile()) { - imgPath = urls[0].toLocalFile(); - } - } - - if (!imgPath.isEmpty()) { - QImage img(imgPath); - if (!img.isNull()) { - VClipboardUtils::setImageToClipboard(clipboard, img, QClipboard::Clipboard); - qDebug() << "clipboard copy image via URL" << imgPath; - return; - } - } - } - - // Fall back. - triggerPageAction(QWebEnginePage::CopyImageToClipboard); -} diff --git a/src/vwebview.h b/src/vwebview.h deleted file mode 100644 index 9bf9c328..00000000 --- a/src/vwebview.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef VWEBVIEW_H -#define VWEBVIEW_H - -#include - -class VFile; - -class VWebView : public QWebEngineView -{ - Q_OBJECT -public: - // @p_file could be NULL. - explicit VWebView(VFile *p_file, QWidget *p_parent = Q_NULLPTR); - -signals: - void editNote(); - -protected: - void contextMenuEvent(QContextMenuEvent *p_event); - -private slots: - void handleEditAction(); - - // Copy the clicked image. - // Used to replace the default CopyImageToClipboard action. - void copyImage(); - -private: - VFile *m_file; - - // Whether this view has hooked the Copy Image Url action. - bool m_actionHooked; -}; - -#endif // VWEBVIEW_H