├── .editorconfig ├── .github ├── FUNDING.yml └── workflows │ └── ci.yml ├── .gitignore ├── .travis.yml ├── AUTHORS ├── LICENSE ├── README.md ├── app ├── com.github.phase1geo.textshine.yml ├── data ├── com.github.phase1geo.textshine.appdata.xml ├── com.github.phase1geo.textshine.appdata.xml.in ├── com.github.phase1geo.textshine.desktop ├── com.github.phase1geo.textshine.desktop.in ├── com.github.phase1geo.textshine.gresource.xml ├── com.github.phase1geo.textshine.gschema.xml ├── com.github.phase1geo.textshine.shortcuts.ui ├── css │ └── style.css ├── images │ ├── com.github.phase1geo.textshine.png │ └── icons │ │ └── scalable │ │ └── com.github.phase1geo.textshine.svg ├── meson.build └── screenshots │ ├── screenshot-actions.png │ └── screenshot-custom.png ├── debian ├── changelog ├── compat ├── control ├── copyright ├── rules └── source │ └── format ├── meson.build ├── meson └── post_install.py ├── meson_options.txt ├── po ├── LINGUAS ├── POTFILES ├── com.github.phase1geo.textshine.pot ├── de.po ├── extra │ ├── LINGUAS │ ├── POTFILES │ ├── de.po │ ├── extra.pot │ ├── it.po │ ├── meson.build │ └── nl.po ├── it.po ├── meson.build └── nl.po ├── src ├── Application.vala ├── Config.vala.in ├── CustomFunction.vala ├── Editor.vala ├── MainWindow.vala ├── Preferences.vala ├── Sidebar.vala ├── SidebarBox.vala ├── SidebarCustom.vala ├── SidebarFunctions.vala ├── SpellChecker.vala ├── TextFunction.vala ├── TextFunctions.vala ├── UndoBuffer.vala ├── UndoCustomBuffer.vala ├── UndoCustomItem.vala ├── UndoItem.vala ├── Utils.vala ├── functions │ ├── case │ │ ├── CaseCamel.vala │ │ ├── CaseLower.vala │ │ ├── CaseRandom.vala │ │ ├── CaseSentence.vala │ │ ├── CaseSnake.vala │ │ ├── CaseTitle.vala │ │ ├── CaseUpper.vala │ │ └── meson.build │ ├── convert │ │ ├── ConvertBase64.vala │ │ ├── ConvertChecksum.vala │ │ ├── ConvertHardWrap.vala │ │ ├── ConvertMarkdownTable.vala │ │ ├── ConvertROT13.vala │ │ ├── ConvertURL.vala │ │ └── meson.build │ ├── indent │ │ ├── Indent.vala │ │ ├── IndentXML.vala │ │ ├── Unindent.vala │ │ └── meson.build │ ├── insert │ │ ├── InsertFile.vala │ │ ├── InsertLineNumbers.vala │ │ ├── InsertLoremIpsum.vala │ │ ├── InsertText.vala │ │ ├── InsertURL.vala │ │ └── meson.build │ ├── markdown │ │ ├── ConvertMarkdownHTML.vala │ │ ├── MarkdownReferences.vala │ │ ├── MarkdownTableBeauty.vala │ │ ├── MarkdownTaskAdd.vala │ │ ├── MarkdownTaskComplete.vala │ │ ├── MarkdownTaskDelete.vala │ │ ├── MarkdownTaskIncomplete.vala │ │ ├── MarkdownTaskRemoveCompleted.vala │ │ └── meson.build │ ├── match │ │ ├── ClearSelected.vala │ │ ├── Find.vala │ │ ├── InvertSelected.vala │ │ ├── RegExpr.vala │ │ ├── ReplaceSelected.vala │ │ └── meson.build │ ├── meson.build │ ├── quotes │ │ ├── QuotesAngled.vala │ │ ├── QuotesCJK.vala │ │ ├── QuotesCurved.vala │ │ ├── QuotesDoubleSingle.vala │ │ ├── QuotesGerman.vala │ │ ├── QuotesStraight.vala │ │ └── meson.build │ ├── remove │ │ ├── RemoveBlankLines.vala │ │ ├── RemoveDuplicateLines.vala │ │ ├── RemoveLeadingWhitespace.vala │ │ ├── RemoveLineBreaks.vala │ │ ├── RemoveLineNumbers.vala │ │ ├── RemoveSelected.vala │ │ ├── RemoveTrailingWhitespace.vala │ │ └── meson.build │ ├── repair │ │ ├── FixSpaces.vala │ │ └── meson.build │ ├── replace │ │ ├── ReplacePeriodsEllipsis.vala │ │ ├── ReplaceReturnSpace.vala │ │ ├── ReplaceReturns.vala │ │ ├── ReplaceTabsSpaces.vala │ │ └── meson.build │ └── sort │ │ ├── Randomize.vala │ │ ├── SortLines.vala │ │ ├── SortMoveLines.vala │ │ ├── SortReverseChars.vala │ │ └── meson.build └── meson.build └── vapi ├── libmarkdown.vapi └── mkdio.h /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = tab 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 120 11 | tab_width = 2 12 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: phase1geo -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | # This workflow will run for any pull request or pushed commit 4 | on: [push, pull_request] 5 | 6 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 7 | jobs: 8 | # This workflow contains a single job called "flatpak" 9 | flatpak: 10 | # The type of runner that the job will run on 11 | runs-on: ubuntu-latest 12 | 13 | # This job runs in a special container designed for building Flatpaks for AppCenter 14 | container: 15 | image: ghcr.io/elementary/flatpak-platform/runtime:6 16 | options: --privileged 17 | 18 | # Steps represent a sequence of tasks that will be executed as part of the job 19 | steps: 20 | # Checks-out your repository under $GITHUB_WORKSPACE, so the job can access it 21 | - uses: actions/checkout@v2 22 | 23 | # Builds your flatpak manifest using the Flatpak Builder action 24 | - uses: bilelmoussaoui/flatpak-github-actions/flatpak-builder@v3 25 | with: 26 | # This is the name of the Bundle file we're building and can be anything you like 27 | bundle: TextShine.flatpak 28 | # This uses your app's RDNN ID 29 | manifest-path: com.github.phase1geo.textshine.yml 30 | 31 | # You can automatically run any of the tests you've created as part of this workflow 32 | run-tests: true 33 | 34 | # These lines specify the location of the elementary Runtime and Sdk 35 | repository-name: appcenter 36 | repository-url: https://flatpak.elementary.io/repo.flatpakrepo 37 | cache-key: "flatpak-builder-${{ github.sha }}" 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build-flatpak/ 2 | build/ 3 | .flatpak-builder 4 | src/*.o 5 | src/*.c 6 | src/undo_actions/*.c 7 | *.swp 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | language: node_js 4 | 5 | node_js: 6 | - 10.17.0 7 | 8 | sudo: required 9 | 10 | services: 11 | - docker 12 | 13 | addons: 14 | apt: 15 | sources: 16 | - ubuntu-toolchain-r-test 17 | packages: 18 | - libstdc++-5-dev 19 | 20 | install: 21 | - npm i -g @elementaryos/houston 22 | 23 | script: 24 | - houston ci 25 | 26 | branches: 27 | only: 28 | - master 29 | - devel 30 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Trevor Williams 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TextShine 2 | 3 | A powerful, graphical text conversion utility. 4 | 5 |

6 | 7 | Get it on AppCenter 8 | 9 |

10 | 11 | ![
Main Window
](https://raw.githubusercontent.com/phase1geo/TextShine/master/data/screenshots/screenshot-actions.png "Text Conversion application for Elementary OS") 12 | 13 | ## Overview 14 | 15 | Easily paste text from the clipboard or load text from a file, modify the text 16 | with loads of built-in text actions and user-created custom text workflows, and 17 | save the changes to the clipboard or to a file. 18 | 19 | In addition to the built-in actions, TextShine allows you to create and test 20 | custom text conversion workflows. These custom workflows can then be used in the 21 | same way that built-in actions are used within the application. 22 | 23 | ## Key Features 24 | 25 | - Load text from clipboard or from a file. 26 | - Save text back to clipboard, to the same file or to a new file. 27 | - Unlimited undo/redo of text changes. 28 | - Apply a text action in a single click. 29 | - Support for action favoriting. 30 | - Support for creating and testing custom actions. 31 | - Quickly search available text actions. 32 | - Character, word, line, match and spelling error statistics. 33 | - Support for font size changes. 34 | - Built-in spell checking. 35 | - Categorized text actions which include: 36 | * Changing case 37 | * Inserting text, line numbers, lorem ipsum and file contents 38 | * Removing line numbers, blank lines/spaces and matched text. 39 | * Replacement of text. 40 | * Quotation conversion 41 | * Line sorting 42 | * Indentation handling 43 | * Search and replace (includes regular expression support) 44 | * Automatic text repair 45 | * Text conversion 46 | * MD5, SHA-1/256/384/512 encoding and Base64 encoding/decoding. 47 | * Markdown utilities 48 | 49 | ## Installation 50 | 51 | You will need the following dependencies to build TextShine: 52 | 53 | * ninja-build 54 | * python3-pip 55 | * python3-setuptools 56 | * meson 57 | * valac (version 0.48.3 or later is recommended) 58 | * debhelper 59 | * libgtk-3-dev 60 | * libxml2-dev 61 | * libgee-0.8-dev 62 | * libgtksourceview-4-dev 63 | * libmarkdown2-dev 64 | * libcamel1.2-dev 65 | * libgranite-dev 66 | * libgtkspell3-3-dev 67 | 68 | From the command-line within the top TextShine directory, run `./app run` to build 69 | and run the application. 70 | 71 | To install, run `sudo ./app install` and then run the application from your 72 | application launcher. 73 | 74 | -------------------------------------------------------------------------------- /app: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | arg=$1 4 | 5 | function initialize { 6 | meson setup build --prefix=/usr 7 | result=$? 8 | 9 | if [ $result -gt 0 ]; then 10 | echo "Unable to initialize, please review log" 11 | exit 1 12 | fi 13 | 14 | cd build 15 | 16 | ninja 17 | 18 | result=$? 19 | 20 | if [ $result -gt 0 ]; then 21 | echo "Unable to build project, please review log" 22 | exit 2 23 | fi 24 | } 25 | 26 | function test { 27 | initialize 0 28 | 29 | export DISPLAY=:0 30 | ./com.github.phase1geo.textshine --run-tests 31 | result=$? 32 | 33 | export DISPLAY=":0.0" 34 | 35 | echo "" 36 | if [ $result -gt 0 ]; then 37 | echo "Failed testing" 38 | exit 100 39 | fi 40 | 41 | echo "Tests passed!" 42 | } 43 | 44 | case $1 in 45 | "clean") 46 | sudo rm -rf ./build 47 | ;; 48 | "generate-i18n") 49 | grep -rc _\( * | grep ^src | grep -v :0 | cut -d : -f 1 | sort -o po/POTFILES 50 | initialize 0 51 | ninja com.github.phase1geo.textshine-pot 52 | ninja com.github.phase1geo.textshine-update-po 53 | ninja extra-pot 54 | ninja extra-update-po 55 | cp data/* ../data 56 | ;; 57 | "install") 58 | initialize 0 59 | sudo ninja install 60 | ;; 61 | "install-deps") 62 | output=$((dpkg-checkbuilddeps ) 2>&1) 63 | result=$? 64 | 65 | if [ $result -eq 0 ]; then 66 | echo "All dependencies are installed" 67 | exit 0 68 | fi 69 | 70 | replace="sudo apt install" 71 | pattern="(\([>=<0-9. ]+\))+" 72 | sudo_replace=${output/dpkg-checkbuilddeps: error: Unmet build dependencies:/$replace} 73 | command=$(sed -r -e "s/$pattern//g" <<< "$sudo_replace") 74 | 75 | $command 76 | ;; 77 | "emmet-true") 78 | cd build 79 | meson configure -Demmet=true 80 | ;; 81 | "emmet-false") 82 | cd build 83 | meson configure -Demmet=false 84 | ;; 85 | "run") 86 | initialize 0 87 | ./com.github.phase1geo.textshine "${@:2}" 88 | ;; 89 | "run-emmet") 90 | initialize 1 91 | ./com.github.phase1geo.textshine "${@:2}" 92 | ;; 93 | "debug") 94 | initialize 0 95 | G_DEBUG=fatal-criticals gdb --args ./com.github.phase1geo.textshine "${@:2}" 96 | # gdb --args ./com.github.phase1geo.textshine "${@:2}" 97 | ;; 98 | "test") 99 | test 100 | ;; 101 | "test-run") 102 | test 103 | ./com.github.phase1geo.textshine "${@:2}" 104 | ;; 105 | "uninstall") 106 | initialize 0 107 | sudo ninja uninstall 108 | ;; 109 | "flatpak") 110 | sudo flatpak-builder --install --force-clean ../build-textshine com.github.phase1geo.textshine.yml 111 | ;; 112 | *) 113 | echo "Usage:" 114 | echo " ./app [OPTION]" 115 | echo "" 116 | echo "Options:" 117 | echo " clean Removes build directories (can require sudo)" 118 | echo " generate-i18n Generates .pot and .po files for i18n (multi-language support)" 119 | echo " emmet- Sets the Emmet build mode to true or false" 120 | echo " install Builds and installs application to the system (requires sudo)" 121 | echo " install-deps Installs missing build dependencies" 122 | echo " run Builds and runs the application (must run install once before successive calls to this command)" 123 | echo " test Builds and runs testing for the application" 124 | echo " test-run Builds application, runs testing and if successful application is started" 125 | echo " uninstall Removes the application from the system (requires sudo)" 126 | echo " flatpak Builds and installs the Flatpak version of the application" 127 | ;; 128 | esac 129 | -------------------------------------------------------------------------------- /com.github.phase1geo.textshine.yml: -------------------------------------------------------------------------------- 1 | # This is the same ID that you've used in meson.build and other files 2 | app-id: com.github.phase1geo.textshine 3 | 4 | # Instead of manually specifying a long list of build and runtime dependencies, 5 | # we can use a convenient pre-made runtime and SDK. For this example, we'll be 6 | # using the runtime and SDK provided by elementary. 7 | runtime: io.elementary.Platform 8 | runtime-version: '8' 9 | sdk: io.elementary.Sdk 10 | 11 | # This should match the exec line in your .desktop file and usually is the same 12 | # as your app ID 13 | command: com.github.phase1geo.textshine 14 | 15 | # Here we can specify the kinds of permissions our app needs to run. Since we're 16 | # not using hardware like webcams, making sound, or reading external files, we 17 | # only need permission to draw our app on screen using either X11 or Wayland. 18 | finish-args: 19 | - '--share=ipc' 20 | - '--socket=fallback-x11' 21 | - '--socket=wayland' 22 | - '--filesystem=home' 23 | 24 | # This section is where you list all the source code required to build your app. 25 | # If we had external dependencies that weren't included in our SDK, we would list 26 | # them here. 27 | modules: 28 | - name: libmarkdown2 29 | buildsystem: simple 30 | sources: 31 | - type: archive 32 | url: https://github.com/Orc/discount/archive/v2.2.3b8.tar.gz 33 | sha256: 5d69aa20c43e0da5ac8509c4f95880720655a9b9e36206c5b5adcbba75f80391 34 | build-commands: 35 | - ./configure.sh --prefix=/app --shared --pkg-config 36 | - make -j1 37 | - sed -e 's|/sbin/ldconfig|/sbin/ldconfig -n|' -i librarian.sh 38 | - make install 39 | - install -m644 libmarkdown.pc /app/lib/pkgconfig/libmarkdown.pc 40 | cleanup: 41 | - /bin 42 | - /include 43 | - /lib/pkgconfig 44 | - name: gtksourceview 45 | buildsystem: meson 46 | sources: 47 | - type: git 48 | url: https://gitlab.gnome.org/GNOME/gtksourceview.git 49 | tag: '4.8.0' 50 | - name: gtkspell 51 | config-opts: 52 | - --disable-gtk-doc 53 | sources: 54 | - type: archive 55 | url: https://downloads.sourceforge.net/gtkspell/gtkspell3-3.0.10.tar.xz 56 | sha256: b040f63836b347eb344f5542443dc254621805072f7141d49c067ecb5a375732 57 | post-install: 58 | - install -p -D -m 0644 "COPYING" -t "${FLATPAK_DEST}/share/licenses/gtkspell/"; 59 | # modules: 60 | # - shared-modules/intltool/intltool-0.51.json 61 | - name: textshine 62 | buildsystem: meson 63 | sources: 64 | - type: dir 65 | path: . 66 | -------------------------------------------------------------------------------- /data/com.github.phase1geo.textshine.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name[de]=TextShine 3 | Name[it]=TextShine 4 | Name[nl]=TextShine 5 | Name=TextShine 6 | GenericName[de]=TextShine 7 | GenericName[it]=TextShine 8 | GenericName[nl]=TextShine 9 | GenericName=TextShine 10 | Comment[de]=Text leistungsstark umwandeln 11 | Comment[it]=Trasforma il testo in modo potente 12 | Comment[nl]=Zet tekst om met dit krachtige hulpmiddel 13 | Comment=Powerfully transform text 14 | Categories=Utility;Development;WordProcessor; 15 | Exec=com.github.phase1geo.textshine %f 16 | Icon=com.github.phase1geo.textshine 17 | Terminal=false 18 | Type=Application 19 | MimeType=text/plain; 20 | X-GNOME-Gettext-Domain=TextShine 21 | X-GNOME-UsesNotifications=true 22 | Keywords[de]=textshine;text;konvertierung;konvertieren; 23 | Keywords[it]=textshine;testo;conversione;converte; 24 | Keywords[nl]=textshine;tekst;conversie;converteren;omzetten; 25 | Keywords=textshine;text;conversion;convert; 26 | Actions=EditClipboard; 27 | 28 | [Desktop Action EditClipboard] 29 | Name[de]=Text in der Zwischenablage bearbeiten 30 | Name[it]=Modifica il testo degli Appunti 31 | Name[nl]=Pas klembordtekst aan 32 | Name=Edit Clipboard Text 33 | Exec=com.github.phase1geo.textshine --use-clipboard 34 | -------------------------------------------------------------------------------- /data/com.github.phase1geo.textshine.desktop.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=TextShine 3 | GenericName=TextShine 4 | Comment=Powerfully transform text 5 | Categories=Utility;Development;WordProcessor; 6 | Exec=com.github.phase1geo.textshine %f 7 | Icon=com.github.phase1geo.textshine 8 | Terminal=false 9 | Type=Application 10 | MimeType=text/plain; 11 | X-GNOME-Gettext-Domain=TextShine 12 | X-GNOME-UsesNotifications=true 13 | Keywords=textshine;text;conversion;convert; 14 | Actions=EditClipboard; 15 | 16 | [Desktop Action EditClipboard] 17 | Name=Edit Clipboard Text 18 | Exec=com.github.phase1geo.textshine --use-clipboard 19 | -------------------------------------------------------------------------------- /data/com.github.phase1geo.textshine.gresource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | com.github.phase1geo.textshine.shortcuts.ui 5 | 6 | 7 | css/style.css 8 | 9 | 10 | -------------------------------------------------------------------------------- /data/com.github.phase1geo.textshine.gschema.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 1000 6 | Most recent width of window 7 | Most recent width of window 8 | 9 | 10 | 800 11 | Most recent height of window 12 | Most recent height of window 13 | 14 | 15 | 375 16 | Width of the sidebar (in pixels) 17 | Width of the sidebar (in pixels) 18 | 19 | 20 | "Sans" 21 | Default font family 22 | Default font family to use for the editor. 23 | 24 | 25 | 12 26 | Default font size 27 | Default font size to use for the editor. 28 | 29 | 30 | true 31 | Determines the expanded state of the custom category 32 | Determines the expanded state of the custom category. 33 | 34 | 35 | true 36 | Determines the expanded state of the favorites category 37 | Determines the expanded state of the favorites category. 38 | 39 | 40 | true 41 | Determines the expanded state of the case category 42 | Determines the expanded state of the case category. 43 | 44 | 45 | true 46 | Determines the expanded state of the insert category 47 | Determines the expanded state of the insert category. 48 | 49 | 50 | true 51 | Determines the expanded state of the remove category 52 | Determines the expanded state of the remove category. 53 | 54 | 55 | true 56 | Determines the expanded state of the replace category 57 | Determines the expanded state of the replace category. 58 | 59 | 60 | true 61 | Determines the expanded state of the quotes category 62 | Determines the expanded state of the quotes category. 63 | 64 | 65 | true 66 | Determines the expanded state of the search/replace category 67 | Determines the expanded state of the search/replace category. 68 | 69 | 70 | true 71 | Determines the expanded state of the sort category 72 | Determines the expanded state of the sort category. 73 | 74 | 75 | true 76 | Determines the expanded state of the indentation category 77 | Determines the expanded state of the indentation category. 78 | 79 | 80 | true 81 | Determines the expanded state of the repair category 82 | Determines the expanded state of the repair category. 83 | 84 | 85 | true 86 | Determines the expanded state of the convert category 87 | Determines the expanded state of the convert category. 88 | 89 | 90 | true 91 | Determines the expanded state of the markdown category 92 | Determines the expanded state of the markdown category. 93 | 94 | 95 | false 96 | Specifies if the editor should be cleared on startup or display the last content. 97 | Specifies if the editor should be cleared on startup or display the last content. 98 | 99 | 100 | false 101 | Enables spell checking 102 | Enables or disables spell checking in the editor 103 | 104 | 105 | "en_US" 106 | Current spell-checker language 107 | Language to be used by the built-in spell checker 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /data/com.github.phase1geo.textshine.shortcuts.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 0 5 | 0 6 | TextShine Shortcuts 7 | global 8 | 9 | 10 | general 11 | General 12 | 1 13 | 14 | 15 | General 16 | general 17 | 1 18 | 19 | 20 | New Editor 21 | <ctrl>n 22 | 1 23 | 24 | 25 | 26 | 27 | New Editor With Clipboard Contents 28 | <ctrl><shift>v 29 | 1 30 | 31 | 32 | 33 | 34 | Open File 35 | <ctrl>o 36 | 1 37 | 38 | 39 | 40 | 41 | Save To File 42 | <ctrl>s 43 | 1 44 | 45 | 46 | 47 | 48 | Copy Editor Content To Clipboard 49 | <ctrl><shift>c 50 | 1 51 | 52 | 53 | 54 | 55 | Show Keyboard Shortcuts 56 | <ctrl>question 57 | 1 58 | 59 | 60 | 61 | 62 | Show Preferences 63 | <ctrl>comma 64 | 1 65 | 66 | 67 | 68 | 69 | Quit 70 | <ctrl>q 71 | 1 72 | 73 | 74 | 75 | 76 | 77 | 78 | Editing 79 | editing 80 | 1 81 | 82 | 83 | Copy Selected Text 84 | <ctrl>c 85 | 1 86 | 87 | 88 | 89 | 90 | Cut Selected Text 91 | <ctrl>x 92 | 1 93 | 94 | 95 | 96 | 97 | Paste 98 | <ctrl>v 99 | 1 100 | 101 | 102 | 103 | 104 | Undo 105 | <ctrl>z 106 | 1 107 | 108 | 109 | 110 | 111 | Redo 112 | <ctrl><shift>z 113 | 1 114 | 115 | 116 | 117 | 118 | Insert Emoji 119 | <ctrl>semicolon 120 | 1 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /data/css/style.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Trevor Williams 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | @define-color colorPrimary #ffe16b; 19 | @define-color textColorPrimary @BLACK_500; 20 | @define-color textColorPrimaryShadow #ffe16b; 21 | 22 | /* 23 | .color-button radio, 24 | .color-button radio.checked { 25 | border-color: alpha (#000, 0.3); 26 | box-shadow: inset 0 1px 0 0 alpha (@inset_dark_color, 0.7), 27 | inset 0 0 0 1px alpha (@inset_dark_color, 0.3), 28 | 0 1px 0 0 alpha (@bg_highlight_color, 0.3); 29 | padding: 10px; 30 | -gtk-icon-shadow: none; 31 | } 32 | 33 | .color-button radio:focus { 34 | border-color: @colorAccent; 35 | box-shadow: inset 0 1px 0 0 alpha (@inset_dark_color, 0.7), 36 | inset 0 0 0 1px alpha (@inset_dark_color, 0.3), 37 | inset 0 0 0 1px alpha (@bg_highlight_color, 0.05), 38 | 0 1px 0 0 alpha (@bg_highlight_color, 0.3), 39 | 0 0 0 1px alpha (@colorAccent, 0.25); 40 | } 41 | */ 42 | 43 | list { 44 | background-color: @bg_color; 45 | } 46 | -------------------------------------------------------------------------------- /data/images/com.github.phase1geo.textshine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phase1geo/TextShine/613f49a4585e82fdf1f34e14cbdf38cdd769ff89/data/images/com.github.phase1geo.textshine.png -------------------------------------------------------------------------------- /data/meson.build: -------------------------------------------------------------------------------- 1 | install_data( 2 | join_paths('images', 'icons', 'scalable', meson.project_name() + '.svg'), 3 | install_dir: join_paths(get_option('datadir'), 'icons', 'hicolor', 'scalable', 'apps') 4 | ) 5 | 6 | i18n.merge_file( 7 | input: meson.project_name() + '.desktop.in', 8 | output: meson.project_name() + '.desktop', 9 | po_dir: join_paths(meson.source_root(), 'po', 'extra'), 10 | type: 'desktop', 11 | install: true, 12 | install_dir: join_paths(get_option('datadir'), 'applications') 13 | ) 14 | 15 | i18n.merge_file( 16 | input: meson.project_name() + '.appdata.xml.in', 17 | output: meson.project_name() + '.appdata.xml', 18 | po_dir: join_paths(meson.source_root(), 'po', 'extra'), 19 | install: true, 20 | install_dir: join_paths(get_option('datadir'), 'metainfo') 21 | ) 22 | 23 | install_data( 24 | meson.project_name() + '.gschema.xml', 25 | install_dir: join_paths(get_option('datadir'), 'glib-2.0', 'schemas') 26 | ) 27 | -------------------------------------------------------------------------------- /data/screenshots/screenshot-actions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phase1geo/TextShine/613f49a4585e82fdf1f34e14cbdf38cdd769ff89/data/screenshots/screenshot-actions.png -------------------------------------------------------------------------------- /data/screenshots/screenshot-custom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phase1geo/TextShine/613f49a4585e82fdf1f34e14cbdf38cdd769ff89/data/screenshots/screenshot-custom.png -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | com.github.phase1geo.textshine (1.0.0) xenial; urgency=low 2 | 3 | * Initial Release 4 | 5 | -- Trevor Williams Tue, 29 May 2018 22:10:00 -0500 6 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: com.github.phase1geo.textshine 2 | Section: x11 3 | Priority: extra 4 | Maintainer: Trevor Williams 5 | Build-Depends: meson, 6 | valac, 7 | debhelper, 8 | libgranite-dev, 9 | libxml2-dev, 10 | libgtk-3-dev, 11 | libgtksourceview-3.0-dev, 12 | libmarkdown2-dev, 13 | libcamel1.2-dev, 14 | libhandy-1-dev 15 | 16 | Standards-Version: 3.9.3 17 | Package: com.github.phase1geo.textshine 18 | Architecture: any 19 | Depends: ${misc:Depends}, ${shlibs:Depends} 20 | Description: Powerful text converter 21 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://dep.debian.net/deps/dep5 2 | Upstream-Name: Outliner 3 | Source: https://github.com/phase1geo/textshine 4 | 5 | Files: * 6 | Copyright: 2020 Trevor Williams 7 | License: GPL-3.0+ 8 | 9 | License: GPL-3.0+ 10 | This program is free software: you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation, either version 3 of the License, or 13 | (at your option) any later version. 14 | . 15 | This package is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU General Public License for more details. 19 | . 20 | You should have received a copy of the GNU General Public License 21 | along with this program. If not, see . 22 | . 23 | On Debian systems, the complete text of the GNU General 24 | Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". 25 | 26 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | #export DH_VERBOSE=1 11 | 12 | %: 13 | dh $@ 14 | 15 | override_dh_shlibdeps: 16 | dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info 17 | 18 | override_dh_auto_clean: 19 | rm -rf debian/build 20 | 21 | override_dh_auto_configure: 22 | mkdir -p debian/build 23 | cd debian/build && meson --prefix=/usr ../.. 24 | 25 | override_dh_auto_build: 26 | cd debian/build && ninja -v 27 | 28 | override_dh_auto_test: 29 | cd debian/build && ninja test 30 | 31 | override_dh_auto_install: 32 | cd debian/build && DESTDIR=${CURDIR}/debian/com.github.phase1geo.textshine ninja install 33 | 34 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project('com.github.phase1geo.textshine', ['vala', 'c'], 2 | version : '2.0', 3 | license: 'GPL-3.0' 4 | ) 5 | 6 | add_project_arguments([ 7 | '-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()) 8 | ], 9 | language: 'c', 10 | ) 11 | 12 | gnome = import('gnome') 13 | i18n = import('i18n') 14 | 15 | gresource = gnome.compile_resources( 16 | 'textshine-resources', 'data/' + meson.project_name() + '.gresource.xml', 17 | source_dir: 'data', 18 | ) 19 | 20 | add_global_arguments('-DGETTEXT_PACKAGE="@0@"'.format (meson.project_name()), language:'c') 21 | 22 | config_data = configuration_data() 23 | config_data.set_quoted('LOCALEDIR', get_option('prefix') / get_option('localedir')) 24 | config_data.set_quoted('GETTEXT_PACKAGE', meson.project_name()) 25 | config_file = configure_file( 26 | input: 'src/Config.vala.in', 27 | output: '@BASENAME@', 28 | configuration: config_data 29 | ) 30 | 31 | sources = files() 32 | 33 | subdir('data') 34 | subdir('po') 35 | subdir('src') 36 | 37 | if get_option('emmet') 38 | sources += lfiles 39 | sources += pfiles 40 | endif 41 | 42 | # Add the math library 43 | cc = meson.get_compiler('c') 44 | math_dep = cc.find_library('m', required: false) 45 | 46 | # Add the Markdown library 47 | cc = meson.get_compiler('c') 48 | libmarkdown = cc.find_library('markdown', required: true) 49 | 50 | add_project_arguments([ 51 | '--vapidir', join_paths(meson.current_source_dir(), 'vapi'), 52 | '--disable-warnings' 53 | ], 54 | language: 'vala', 55 | ) 56 | 57 | dependencies = [ 58 | dependency('gobject-2.0'), 59 | dependency('glib-2.0'), 60 | dependency('gee-0.8'), 61 | dependency('granite-7'), 62 | dependency('gtk4'), 63 | dependency('libxml-2.0'), 64 | dependency('gtksourceview-5'), 65 | dependency('enchant-2'), 66 | libmarkdown, 67 | math_dep 68 | ] 69 | 70 | e = executable('com.github.phase1geo.textshine', 71 | sources, 72 | config_file, 73 | gresource, 74 | dependencies: dependencies, 75 | vala_args: [ 76 | meson.source_root() + '/vapi/libmarkdown.vapi' 77 | ], 78 | install : true 79 | ) 80 | 81 | # Perform post install operations 82 | gnome.post_install( 83 | glib_compile_schemas: true, 84 | gtk_update_icon_cache: true, 85 | update_desktop_database: true 86 | ) 87 | -------------------------------------------------------------------------------- /meson/post_install.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from os import path, environ 4 | import subprocess 5 | 6 | prefix = environ.get('MESON_INSTALL_PREFIX', '/usr/local') 7 | schemadir = path.join(environ['MESON_INSTALL_PREFIX'], 'share', 'glib-2.0', 'schemas') 8 | datadir = path.join(prefix, 'share') 9 | 10 | if not environ.get('DESTDIR'): 11 | print('Compiling gsettings schemas…') 12 | subprocess.call(['glib-compile-schemas', schemadir]) 13 | print('Updating icon cache…') 14 | subprocess.call(['gtk-update-icon-cache', '-qtf', path.join(datadir, 'icons', 'hicolor')]) 15 | print('Compiling mime types…') 16 | subprocess.call(['update-mime-database', path.join(datadir, 'mime')]) 17 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option('emmet', type : 'boolean', value : false) 2 | -------------------------------------------------------------------------------- /po/LINGUAS: -------------------------------------------------------------------------------- 1 | de 2 | it 3 | nl 4 | -------------------------------------------------------------------------------- /po/POTFILES: -------------------------------------------------------------------------------- 1 | src/Application.vala 2 | src/functions/case/CaseCamel.vala 3 | src/functions/case/CaseLower.vala 4 | src/functions/case/CaseRandom.vala 5 | src/functions/case/CaseSentence.vala 6 | src/functions/case/CaseSnake.vala 7 | src/functions/case/CaseTitle.vala 8 | src/functions/case/CaseUpper.vala 9 | src/functions/convert/ConvertBase64.vala 10 | src/functions/convert/ConvertChecksum.vala 11 | src/functions/convert/ConvertHardWrap.vala 12 | src/functions/convert/ConvertMarkdownTable.vala 13 | src/functions/convert/ConvertROT13.vala 14 | src/functions/convert/ConvertURL.vala 15 | src/functions/indent/Indent.vala 16 | src/functions/indent/IndentXML.vala 17 | src/functions/indent/Unindent.vala 18 | src/functions/insert/InsertFile.vala 19 | src/functions/insert/InsertLineNumbers.vala 20 | src/functions/insert/InsertLoremIpsum.vala 21 | src/functions/insert/InsertText.vala 22 | src/functions/insert/InsertURL.vala 23 | src/functions/markdown/ConvertMarkdownHTML.vala 24 | src/functions/markdown/MarkdownReferences.vala 25 | src/functions/markdown/MarkdownTableBeauty.vala 26 | src/functions/markdown/MarkdownTaskAdd.vala 27 | src/functions/markdown/MarkdownTaskComplete.vala 28 | src/functions/markdown/MarkdownTaskDelete.vala 29 | src/functions/markdown/MarkdownTaskIncomplete.vala 30 | src/functions/markdown/MarkdownTaskRemoveCompleted.vala 31 | src/functions/match/ClearSelected.vala 32 | src/functions/match/Find.vala 33 | src/functions/match/InvertSelected.vala 34 | src/functions/match/RegExpr.vala 35 | src/functions/match/ReplaceSelected.vala 36 | src/functions/quotes/QuotesAngled.vala 37 | src/functions/quotes/QuotesCJK.vala 38 | src/functions/quotes/QuotesCurved.vala 39 | src/functions/quotes/QuotesDoubleSingle.vala 40 | src/functions/quotes/QuotesGerman.vala 41 | src/functions/quotes/QuotesStraight.vala 42 | src/functions/remove/RemoveBlankLines.vala 43 | src/functions/remove/RemoveDuplicateLines.vala 44 | src/functions/remove/RemoveLeadingWhitespace.vala 45 | src/functions/remove/RemoveLineBreaks.vala 46 | src/functions/remove/RemoveLineNumbers.vala 47 | src/functions/remove/RemoveSelected.vala 48 | src/functions/remove/RemoveTrailingWhitespace.vala 49 | src/functions/repair/FixSpaces.vala 50 | src/functions/replace/ReplacePeriodsEllipsis.vala 51 | src/functions/replace/ReplaceReturnSpace.vala 52 | src/functions/replace/ReplaceReturns.vala 53 | src/functions/replace/ReplaceTabsSpaces.vala 54 | src/functions/sort/Randomize.vala 55 | src/functions/sort/SortLines.vala 56 | src/functions/sort/SortMoveLines.vala 57 | src/functions/sort/SortReverseChars.vala 58 | src/MainWindow.vala 59 | src/Preferences.vala 60 | src/SidebarCustom.vala 61 | src/SidebarFunctions.vala 62 | src/SpellChecker.vala 63 | src/TextFunctions.vala 64 | src/UndoBuffer.vala 65 | src/UndoCustomBuffer.vala 66 | src/UndoCustomItem.vala 67 | src/Utils.vala 68 | -------------------------------------------------------------------------------- /po/extra/LINGUAS: -------------------------------------------------------------------------------- 1 | de 2 | it 3 | nl 4 | -------------------------------------------------------------------------------- /po/extra/POTFILES: -------------------------------------------------------------------------------- 1 | data/com.github.phase1geo.textshine.desktop.in 2 | data/com.github.phase1geo.textshine.appdata.xml.in 3 | -------------------------------------------------------------------------------- /po/extra/meson.build: -------------------------------------------------------------------------------- 1 | i18n.gettext('extra', 2 | args: [ 3 | '--directory=' + meson.source_root(), 4 | '--from-code=UTF-8' 5 | ], 6 | install: false 7 | ) -------------------------------------------------------------------------------- /po/meson.build: -------------------------------------------------------------------------------- 1 | i18n.gettext(meson.project_name(), 2 | args: [ 3 | '--directory='+meson.source_root(), 4 | '--from-code=UTF-8' 5 | ] 6 | ) 7 | 8 | subdir('extra') 9 | -------------------------------------------------------------------------------- /src/Application.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | using Gdk; 24 | using GLib; 25 | 26 | public class TextShine : Gtk.Application { 27 | 28 | private static bool show_version = false; 29 | private MainWindow appwin; 30 | 31 | public static GLib.Settings settings; 32 | public static bool use_clipboard = false; 33 | public static string version = "2.0"; 34 | 35 | public TextShine () { 36 | 37 | Object( application_id: "com.github.phase1geo.textshine", flags: ApplicationFlags.HANDLES_OPEN ); 38 | 39 | Intl.setlocale( LocaleCategory.ALL, "" ); 40 | Intl.bindtextdomain( GETTEXT_PACKAGE, LOCALEDIR ); 41 | Intl.bind_textdomain_codeset( GETTEXT_PACKAGE, "UTF-8" ); 42 | Intl.textdomain( GETTEXT_PACKAGE ); 43 | 44 | startup.connect( start_application ); 45 | open.connect( open_files ); 46 | 47 | } 48 | 49 | /* First method called in the startup process */ 50 | private void start_application() { 51 | 52 | /* Initialize the settings */ 53 | settings = new GLib.Settings( "com.github.phase1geo.textshine" ); 54 | 55 | /* Add the application-specific icons */ 56 | weak IconTheme default_theme = IconTheme.get_for_display( Display.get_default() ); 57 | default_theme.add_resource_path( "/com/github/phase1geo/textshine" ); 58 | 59 | /* Create the main window */ 60 | appwin = new MainWindow( this ); 61 | 62 | /* Initialize the editor with the clipboard contents */ 63 | if( use_clipboard ) { 64 | appwin.do_paste_over(); 65 | } 66 | 67 | } 68 | 69 | /* Called whenever files need to be opened */ 70 | private void open_files( File[] files, string hint ) { 71 | foreach( File open_file in files ) { 72 | var file = open_file.get_path(); 73 | appwin.notification( _( "Opening file" ), file ); 74 | if( !appwin.open_file( file ) ) { 75 | stdout.printf( "ERROR: Unable to open file '%s'\n", file ); 76 | } 77 | } 78 | } 79 | 80 | /* Called if we have no files to open */ 81 | protected override void activate() {} 82 | 83 | /* Parse the command-line arguments */ 84 | private void parse_arguments( ref unowned string[] args ) { 85 | 86 | var context = new OptionContext( "- TextShine Options" ); 87 | var options = new OptionEntry[3]; 88 | 89 | /* Create the command-line options */ 90 | options[0] = {"version", 0, 0, OptionArg.NONE, ref show_version, _( "Display version number" ), null}; 91 | options[1] = {"use-clipboard", 0, 0, OptionArg.NONE, ref use_clipboard, _( "Transform clipboard text" ), null}; 92 | options[2] = {null}; 93 | 94 | /* Parse the arguments */ 95 | try { 96 | context.set_help_enabled( true ); 97 | context.add_main_entries( options, null ); 98 | context.parse( ref args ); 99 | } catch( OptionError e ) { 100 | stdout.printf( "ERROR: %s\n", e.message ); 101 | stdout.printf( "Run '%s --help' to see valid options\n", args[0] ); 102 | Process.exit( 1 ); 103 | } 104 | 105 | /* If the version was specified, output it and then exit */ 106 | if( show_version ) { 107 | stdout.printf( version + "\n" ); 108 | Process.exit( 0 ); 109 | } 110 | 111 | } 112 | 113 | /* Creates the home directory and returns it */ 114 | public static string get_home_dir() { 115 | var dir = GLib.Path.build_filename( Environment.get_user_data_dir(), "textshine" ); 116 | DirUtils.create_with_parents( dir, 0775 ); 117 | return( dir ); 118 | } 119 | 120 | /* Main routine which gets everything started */ 121 | public static int main( string[] args ) { 122 | 123 | var app = new TextShine(); 124 | app.parse_arguments( ref args ); 125 | 126 | return( app.run( args ) ); 127 | 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /src/Config.vala.in: -------------------------------------------------------------------------------- 1 | public const string GETTEXT_PACKAGE = @GETTEXT_PACKAGE@; 2 | public const string LOCALEDIR = @LOCALEDIR@; 3 | -------------------------------------------------------------------------------- /src/CustomFunction.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public delegate void CustomDeleteFunc( CustomFunction function ); 25 | public delegate void CustomSaveFunc( CustomFunction function ); 26 | 27 | public class CustomFunction : TextFunction { 28 | 29 | private static int custom_id = 1; 30 | 31 | private Array _functions; 32 | private string _label; 33 | private int _breakpoint; 34 | private string _description; 35 | 36 | public Array functions { 37 | get { 38 | return( _functions ); 39 | } 40 | } 41 | public string label { 42 | get { 43 | return( _label ); 44 | } 45 | set { 46 | _label = value; 47 | } 48 | } 49 | public int breakpoint { 50 | get { 51 | return( _breakpoint ); 52 | } 53 | set { 54 | _breakpoint = (value < _functions.length) ? value : -1; 55 | } 56 | } 57 | public string description { 58 | get { 59 | return( _description ); 60 | } 61 | set { 62 | _description = value; 63 | } 64 | } 65 | 66 | /* Constructor */ 67 | public CustomFunction( bool custom = false ) { 68 | base( "custom-%d".printf( custom_id ), custom ); 69 | _label = "Custom #%d".printf( custom_id++ ); 70 | _functions = new Array(); 71 | _breakpoint = -1; 72 | } 73 | 74 | /* Copy constructor */ 75 | public CustomFunction.copy_function( CustomFunction func ) { 76 | base( func.name, true ); 77 | _label = func.label; 78 | _functions = new Array(); 79 | for( int i=0; iset_prop( "name", name ); 135 | node->set_prop( "label", _label ); 136 | node->set_prop( "description", _description ); 137 | for( int i=0; i<_functions.length; i++ ) { 138 | node->add_child( _functions.index( i ).save() ); 139 | } 140 | return( node ); 141 | } 142 | 143 | /* Loads the contents of this text function */ 144 | public override void load( Xml.Node* node, TextFunctions functions ) { 145 | _label = node->get_prop( "label" ); 146 | _description = node->get_prop( "description" ); 147 | for( Xml.Node* it=node->children; it!=null; it=it->next ) { 148 | if( (it->type == Xml.ElementType.ELEMENT_NODE) && (it->name == "function") ) { 149 | var function = functions.get_function_by_name( it->get_prop( "name" ) ).copy( true ); 150 | function.load( it, functions ); 151 | _functions.append_val( function ); 152 | } 153 | } 154 | } 155 | 156 | } 157 | 158 | -------------------------------------------------------------------------------- /src/Preferences.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class Preferences : Dialog { 25 | 26 | private MainWindow _win; 27 | private FontButton _font; 28 | private MenuButton _spell_lang; 29 | 30 | private const GLib.ActionEntry action_entries[] = { 31 | { "action_spell_menu", action_spell_menu, "s" } 32 | }; 33 | 34 | /* Default constructor */ 35 | public Preferences( MainWindow win ) { 36 | 37 | Object( 38 | resizable: false, 39 | title: _( "Preferences" ), 40 | transient_for: win, 41 | modal: true 42 | ); 43 | 44 | _win = win; 45 | 46 | var box = new Box( Orientation.VERTICAL, 10 ) { 47 | margin_start = 10, 48 | margin_end = 10, 49 | margin_top = 10, 50 | margin_bottom = 10 51 | }; 52 | 53 | /* Add the preference items */ 54 | box.append( create_font_selection() ); 55 | box.append( create_spell_checker() ); 56 | box.append( create_spell_checker_language() ); 57 | 58 | /* Set the content area of the dialog box */ 59 | get_content_area().append( box ); 60 | 61 | /* Add the menu actions */ 62 | var actions = new SimpleActionGroup(); 63 | actions.add_action_entries( action_entries, this ); 64 | insert_action_group( "prefs", actions ); 65 | 66 | } 67 | 68 | /* Create font selection box */ 69 | private Box create_font_selection() { 70 | 71 | var lbl = new Label( _( "Font:" ) ) { 72 | halign = Align.START, 73 | hexpand = true 74 | }; 75 | 76 | _font = new FontButton() { 77 | halign = Align.END, 78 | hexpand = true 79 | }; 80 | 81 | _font.set_filter_func( (family, face) => { 82 | var fd = face.describe(); 83 | var weight = fd.get_weight(); 84 | var style = fd.get_style(); 85 | return( (weight == Pango.Weight.NORMAL) && (style == Pango.Style.NORMAL) ); 86 | }); 87 | 88 | _font.font_set.connect(() => { 89 | var name = _font.get_font_family().get_name(); 90 | var size = _font.get_font_size() / Pango.SCALE; 91 | _win.editor.change_name_font( name, size ); 92 | TextShine.settings.set_string( "default-font-family", name ); 93 | TextShine.settings.set_int( "default-font-size", size ); 94 | }); 95 | 96 | /* Set the font button defaults */ 97 | var fd = _font.get_font_desc(); 98 | fd.set_family( TextShine.settings.get_string( "default-font-family" ) ); 99 | fd.set_size( TextShine.settings.get_int( "default-font-size" ) * Pango.SCALE ); 100 | _font.set_font_desc( fd ); 101 | 102 | var box = new Box( Orientation.HORIZONTAL, 10 ); 103 | box.append( lbl ); 104 | box.append( _font ); 105 | 106 | return( box ); 107 | 108 | } 109 | 110 | private Box create_spell_checker() { 111 | 112 | var lbl = new Label( _( "Enable Spell Checker:" ) ) { 113 | halign = Align.START, 114 | hexpand = true 115 | }; 116 | 117 | var sw = new Switch() { 118 | halign = Align.END, 119 | hexpand = true, 120 | active = TextShine.settings.get_boolean( "enable-spell-checking" ) 121 | }; 122 | 123 | sw.notify["active"].connect(() => { 124 | TextShine.settings.set_boolean( "enable-spell-checking", sw.active ); 125 | _win.editor.set_spellchecker(); 126 | }); 127 | 128 | var box = new Box( Orientation.HORIZONTAL, 10 ); 129 | box.append( lbl ); 130 | box.append( sw ); 131 | 132 | return( box ); 133 | 134 | } 135 | 136 | /* Create the spell checker language menu */ 137 | private GLib.Menu create_spell_lang_menu() { 138 | 139 | var menu = new GLib.Menu(); 140 | var langs = new Gee.ArrayList(); 141 | 142 | _win.editor.spell.get_language_list( langs ); 143 | 144 | var sys_menu = new GLib.Menu(); 145 | sys_menu.append( _( "Use System Language" ), "win.action_spell_menu('system')" ); 146 | 147 | var other_menu = new GLib.Menu(); 148 | langs.foreach((lang) => { 149 | other_menu.append( lang, "prefs.action_spell_menu('%s')".printf( lang ) ); 150 | return( true ); 151 | }); 152 | 153 | menu.append_section( null, sys_menu ); 154 | menu.append_section( null, other_menu ); 155 | 156 | return( menu ); 157 | 158 | } 159 | 160 | /* Handles changes to the spell checker language menu */ 161 | private void action_spell_menu( SimpleAction action, Variant? variant ) { 162 | 163 | if( variant != null ) { 164 | var lang = variant.get_string(); 165 | if( lang == "system" ) { 166 | lang = _( "Use System Language" ); 167 | } 168 | _spell_lang.label = lang; 169 | TextShine.settings.set_string( "spell-language", lang ); 170 | } 171 | 172 | } 173 | 174 | /* Creates the UI to adjust the spell checker language */ 175 | private Box create_spell_checker_language() { 176 | 177 | var lbl = new Label( _( "Spell Checker Language:" ) ) { 178 | halign = Align.START, 179 | hexpand = true 180 | }; 181 | 182 | var menu = create_spell_lang_menu(); 183 | 184 | var lang = TextShine.settings.get_string( "spell-language" ); 185 | if( lang == "system" ) { 186 | lang = _( "Use System Language" ); 187 | } 188 | 189 | _spell_lang = new MenuButton() { 190 | label = lang, 191 | menu_model = menu 192 | }; 193 | 194 | var box = new Box( Orientation.HORIZONTAL, 10 ); 195 | box.append( lbl ); 196 | box.append( _spell_lang ); 197 | 198 | return( box ); 199 | 200 | } 201 | 202 | } 203 | -------------------------------------------------------------------------------- /src/Sidebar.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | using Gdk; 24 | using Gee; 25 | 26 | public class Functions { 27 | private TextFunction _func; 28 | private Button? _favorite; 29 | private Widget _widget1; 30 | private Widget? _widget2; 31 | private Expander? _exp; 32 | public TextFunction func { 33 | get { 34 | return( _func ); 35 | } 36 | } 37 | public delegate void UpdateButtonStateFunc( Button btn ); 38 | public Functions( TextFunction func, Button? favorite, Widget widget1, Widget? widget2 = null, Expander? exp = null ) { 39 | _func = func; 40 | _favorite = favorite; 41 | _widget1 = widget1; 42 | _widget2 = widget2; 43 | _exp = exp; 44 | } 45 | public void reveal( string value ) { 46 | var contains = _func.label.down().contains( value ); 47 | if( contains ) { 48 | _widget1.show(); 49 | if( _widget2 != null ) { 50 | _widget2.show(); 51 | } 52 | } else { 53 | _widget1.hide(); 54 | if( _widget2 != null ) { 55 | _widget2.hide(); 56 | } 57 | } 58 | if( (_exp != null) && contains ) { 59 | _exp.expanded = true; 60 | } 61 | } 62 | public bool unfavorite( TextFunction function, UpdateButtonStateFunc func ) { 63 | if( _func.matches( function ) && (_favorite != null) ) { 64 | func( _favorite ); 65 | return( true ); 66 | } 67 | return( false ); 68 | } 69 | } 70 | 71 | public enum SwitchStackReason { 72 | NONE, /* There is no reason for switching */ 73 | NEW, /* We are creating a new cuastom function */ 74 | EDIT, /* We are editing an existing function */ 75 | ADD, /* We are adding a new custom function */ 76 | DELETE /* We are deleting a custom function */ 77 | } 78 | 79 | public class Sidebar : Box { 80 | 81 | private Stack _stack; 82 | 83 | public signal void action_applied( TextFunction function ); 84 | 85 | /* Constructor */ 86 | public Sidebar( MainWindow win, Editor editor ) { 87 | 88 | Object( orientation: Orientation.VERTICAL, spacing: 10, halign: Align.END, hexpand: false ); 89 | 90 | _stack = new Stack(); 91 | 92 | var functions = new SidebarFunctions( win, editor ); 93 | var custom = new SidebarCustom( win, editor ); 94 | 95 | functions.action_applied.connect((fn) => { 96 | action_applied( fn ); 97 | }); 98 | functions.switch_stack.connect((reason, fn) => { 99 | _stack.visible_child_name = "custom"; 100 | custom.displayed( reason, fn ); 101 | }); 102 | 103 | custom.action_applied.connect((fn) => { 104 | action_applied( fn ); 105 | }); 106 | custom.switch_stack.connect((reason,fn) => { 107 | _stack.visible_child_name = "functions"; 108 | functions.displayed( reason, fn ); 109 | }); 110 | 111 | _stack.add_named( functions, "functions" ); 112 | _stack.add_named( custom, "custom" ); 113 | 114 | append( _stack ); 115 | 116 | } 117 | 118 | } 119 | 120 | -------------------------------------------------------------------------------- /src/SidebarBox.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class SidebarBox : Box { 25 | 26 | protected MainWindow win; 27 | protected Editor editor; 28 | protected int width; 29 | protected const int height = 600; 30 | 31 | public signal void action_applied( TextFunction function ); 32 | public signal void switch_stack( SwitchStackReason reason, TextFunction? function ); 33 | 34 | /* Constructor */ 35 | public SidebarBox( MainWindow win, Editor editor ) { 36 | 37 | Object( orientation: Orientation.VERTICAL, spacing: 10 ); 38 | 39 | width = TextShine.settings.get_int( "sidebar-width" ); 40 | 41 | set_size_request( width, height ); 42 | 43 | this.win = win; 44 | this.editor = editor; 45 | 46 | } 47 | 48 | /* Called by sidebar when the stack switches to display this element */ 49 | public virtual void displayed( SwitchStackReason reason, TextFunction? function ) {} 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/UndoBuffer.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 (https://github.com/phase1geo/Minder) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using GLib; 23 | 24 | public class UndoBuffer : Object { 25 | 26 | protected Editor _editor; 27 | protected Array _undo_buffer; 28 | protected Array _redo_buffer; 29 | private bool _debug = false; 30 | private static int _current_id = 0; 31 | 32 | public signal void buffer_changed( UndoBuffer buf ); 33 | 34 | /* Default constructor */ 35 | public UndoBuffer( Editor editor ) { 36 | _editor = editor; 37 | _undo_buffer = new Array(); 38 | _redo_buffer = new Array(); 39 | } 40 | 41 | /* Clear the undo/redo buffers */ 42 | public void clear() { 43 | _undo_buffer.remove_range( 0, _undo_buffer.length ); 44 | _redo_buffer.remove_range( 0, _redo_buffer.length ); 45 | buffer_changed( this ); 46 | } 47 | 48 | /* Returns true if we can perform an undo action */ 49 | public bool undoable() { 50 | return( _undo_buffer.length > 0 ); 51 | } 52 | 53 | /* Returns true if we can perform a redo action */ 54 | public bool redoable() { 55 | return( _redo_buffer.length > 0 ); 56 | } 57 | 58 | /* Performs the next undo action in the buffer */ 59 | public virtual void undo() { 60 | if( undoable() ) { 61 | UndoItem item = _undo_buffer.index( _undo_buffer.length - 1 ); 62 | item.undo( _editor ); 63 | _undo_buffer.remove_index( _undo_buffer.length - 1 ); 64 | _redo_buffer.append_val( item ); 65 | buffer_changed( this ); 66 | } 67 | output( "AFTER UNDO" ); 68 | } 69 | 70 | /* Performs the next redo action in the buffer */ 71 | public virtual void redo() { 72 | if( redoable() ) { 73 | UndoItem item = _redo_buffer.index( _redo_buffer.length - 1 ); 74 | item.redo( _editor ); 75 | _redo_buffer.remove_index( _redo_buffer.length - 1 ); 76 | _undo_buffer.append_val( item ); 77 | buffer_changed( this ); 78 | } 79 | output( "AFTER REDO" ); 80 | } 81 | 82 | /* Returns the undo tooltip */ 83 | public string undo_tooltip() { 84 | if( _undo_buffer.length == 0 ) return( _( "Undo" ) ); 85 | return( _( "Undo " ) + _undo_buffer.index( _undo_buffer.length - 1 ).name ); 86 | } 87 | 88 | /* Returns the undo tooltip */ 89 | public string redo_tooltip() { 90 | if( _redo_buffer.length == 0 ) return( _( "Redo" ) ); 91 | return( _( "Redo " ) + _redo_buffer.index( _redo_buffer.length - 1 ).name ); 92 | } 93 | 94 | /* Adds a new undo item to the undo buffer. Clears the redo buffer. */ 95 | public void add_item( UndoItem item ) { 96 | item.id = _current_id++; 97 | _undo_buffer.append_val( item ); 98 | _redo_buffer.remove_range( 0, _redo_buffer.length ); 99 | buffer_changed( this ); 100 | output( "ITEM ADDED" ); 101 | } 102 | 103 | /* 104 | Returns a handle to the last item in the undo buffer if it is considered to be 105 | mergeable with an edit insert or delete operation; otherwise, returns null. 106 | */ 107 | public UndoItem? get_mergeable( bool insert, int start, int end ) { 108 | if( _undo_buffer.length == 0 ) return( null ); 109 | var last = _undo_buffer.index( _undo_buffer.length - 1 ); 110 | return( last.mergeable( insert, start, end ) ? last : null ); 111 | } 112 | 113 | /* Outputs the state of the undo and redo buffers to standard output */ 114 | public void output( string msg = "BUFFER STATE" ) { 115 | if( _debug ) { 116 | stdout.printf( "%s\n Undo Buffer\n-----------\n", msg ); 117 | for( int i=0; i<_undo_buffer.length; i++ ) { 118 | stdout.printf( " %s\n", _undo_buffer.index( i ).to_string() ); 119 | } 120 | stdout.printf( " Redo Buffer\n-----------\n" ); 121 | for( int i=0; i<_redo_buffer.length; i++ ) { 122 | stdout.printf( " %s\n", _redo_buffer.index( i ).to_string() ); 123 | } 124 | } 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /src/UndoCustomBuffer.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 (https://github.com/phase1geo/Minder) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using GLib; 23 | 24 | public class UndoCustomBuffer : Object { 25 | 26 | protected SidebarCustom _sidebar; 27 | protected Array _undo_buffer; 28 | protected Array _redo_buffer; 29 | 30 | public signal void buffer_changed( UndoCustomBuffer buf ); 31 | 32 | /* Default constructor */ 33 | public UndoCustomBuffer( SidebarCustom sidebar ) { 34 | _sidebar = sidebar; 35 | _undo_buffer = new Array(); 36 | _redo_buffer = new Array(); 37 | } 38 | 39 | /* Clear the undo/redo buffers */ 40 | public void clear() { 41 | _undo_buffer.remove_range( 0, _undo_buffer.length ); 42 | _redo_buffer.remove_range( 0, _redo_buffer.length ); 43 | buffer_changed( this ); 44 | } 45 | 46 | /* Returns true if we can perform an undo action */ 47 | public bool undoable() { 48 | return( _undo_buffer.length > 0 ); 49 | } 50 | 51 | /* Returns true if we can perform a redo action */ 52 | public bool redoable() { 53 | return( _redo_buffer.length > 0 ); 54 | } 55 | 56 | /* Performs the next undo action in the buffer */ 57 | public virtual void undo() { 58 | if( undoable() ) { 59 | UndoCustomItem item = _undo_buffer.index( _undo_buffer.length - 1 ); 60 | item.undo( _sidebar ); 61 | _undo_buffer.remove_index( _undo_buffer.length - 1 ); 62 | _redo_buffer.append_val( item ); 63 | buffer_changed( this ); 64 | } 65 | } 66 | 67 | /* Performs the next redo action in the buffer */ 68 | public virtual void redo() { 69 | if( redoable() ) { 70 | UndoCustomItem item = _redo_buffer.index( _redo_buffer.length - 1 ); 71 | item.redo( _sidebar ); 72 | _redo_buffer.remove_index( _redo_buffer.length - 1 ); 73 | _undo_buffer.append_val( item ); 74 | buffer_changed( this ); 75 | } 76 | } 77 | 78 | /* Returns the undo tooltip */ 79 | public string undo_tooltip() { 80 | if( _undo_buffer.length == 0 ) return( _( "Undo" ) ); 81 | return( _( "Undo " ) + _undo_buffer.index( _undo_buffer.length - 1 ).name ); 82 | } 83 | 84 | /* Returns the undo tooltip */ 85 | public string redo_tooltip() { 86 | if( _redo_buffer.length == 0 ) return( _( "Redo" ) ); 87 | return( _( "Redo " ) + _redo_buffer.index( _redo_buffer.length - 1 ).name ); 88 | } 89 | 90 | /* Adds a new undo item to the undo buffer. Clears the redo buffer. */ 91 | public void add_item( UndoCustomItem item ) { 92 | _undo_buffer.append_val( item ); 93 | _redo_buffer.remove_range( 0, _redo_buffer.length ); 94 | buffer_changed( this ); 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/UndoCustomItem.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 (https://github.com/phase1geo/Minder) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using GLib; 23 | using Gtk; 24 | 25 | public class UndoCustomItem : GLib.Object { 26 | private string _name; 27 | public string name { 28 | get { 29 | return( _name ); 30 | } 31 | } 32 | public UndoCustomItem( string name) { 33 | _name = name; 34 | } 35 | public virtual void undo( SidebarCustom sidebar ) {} 36 | public virtual void redo( SidebarCustom sidebar ) {} 37 | } 38 | 39 | public class UndoCustomAddItem : UndoCustomItem { 40 | private TextFunction _function; 41 | private int _index; 42 | public UndoCustomAddItem( TextFunction function, int index ) { 43 | base( _( "Action Add" ) ); 44 | _function = function; 45 | _index = index; 46 | } 47 | public override void undo( SidebarCustom sidebar ) { 48 | sidebar.delete_function( _index ); 49 | } 50 | public override void redo( SidebarCustom sidebar ) { 51 | sidebar.insert_function( _function, _index ); 52 | } 53 | } 54 | 55 | public class UndoCustomDeleteItem : UndoCustomItem { 56 | private TextFunction _function; 57 | private int _index; 58 | public UndoCustomDeleteItem( TextFunction function, int index ) { 59 | base( _( "Action Remove" ) ); 60 | _function = function; 61 | _index = index; 62 | } 63 | public override void undo( SidebarCustom sidebar ) { 64 | sidebar.insert_function( _function, _index ); 65 | } 66 | public override void redo( SidebarCustom sidebar ) { 67 | sidebar.delete_function( _index ); 68 | } 69 | } 70 | 71 | public class UndoCustomMoveItem : UndoCustomItem { 72 | private int _old_index; 73 | private int _new_index; 74 | public UndoCustomMoveItem( int old_index, int new_index ) { 75 | base( _( "Action Move" ) ); 76 | _old_index = old_index; 77 | _new_index = new_index; 78 | } 79 | public override void undo( SidebarCustom sidebar ) { 80 | sidebar.move_function( _new_index, _old_index ); 81 | } 82 | public override void redo( SidebarCustom sidebar ) { 83 | sidebar.move_function( _old_index, _new_index ); 84 | } 85 | } 86 | 87 | -------------------------------------------------------------------------------- /src/UndoItem.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 (https://github.com/phase1geo/Minder) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using GLib; 23 | using Gtk; 24 | 25 | public class UndoItem : GLib.Object { 26 | 27 | private class UndoElement { 28 | public UndoElement() {} 29 | public virtual void undo( Editor editor ) {} 30 | public virtual void redo( Editor editor ) {} 31 | public virtual bool mergeable( bool insert, int start, int end ) { return( false ); } 32 | } 33 | 34 | private class UndoReplaceElement : UndoElement { 35 | private int _start; 36 | private string _old_text; 37 | private string _new_text; 38 | public UndoReplaceElement( int start, string old_text, string new_text ) { 39 | _start = start; 40 | _old_text = old_text; 41 | _new_text = new_text; 42 | } 43 | private void replace( Editor editor, string curr, string prev ) { 44 | TextIter start, end; 45 | editor.buffer.get_iter_at_offset( out start, _start ); 46 | if( curr.length > 0 ) { 47 | editor.buffer.get_iter_at_offset( out end, (_start + curr.char_count()) ); 48 | editor.delete_text( ref start, ref end ); 49 | } 50 | editor.insert_text( ref start, prev ); 51 | } 52 | public override void undo( Editor editor ) { 53 | replace( editor, _new_text, _old_text ); 54 | } 55 | public override void redo( Editor editor ) { 56 | replace( editor, _old_text, _new_text ); 57 | } 58 | } 59 | 60 | private class UndoSelectElement : UndoElement { 61 | private bool _add; 62 | private int _start; 63 | private int _end; 64 | public UndoSelectElement( bool add, int start, int end ) { 65 | _add = add; 66 | _start = start; 67 | _end = end; 68 | } 69 | public override void undo( Editor editor ) { 70 | TextIter start, end; 71 | editor.buffer.get_iter_at_offset( out start, _start ); 72 | editor.buffer.get_iter_at_offset( out end, _end ); 73 | if( _add ) { 74 | editor.buffer.remove_tag_by_name( "selected", start, end ); 75 | } else { 76 | editor.buffer.apply_tag_by_name( "selected", start, end ); 77 | } 78 | } 79 | public override void redo( Editor editor ) { 80 | TextIter start, end; 81 | editor.buffer.get_iter_at_offset( out start, _start ); 82 | editor.buffer.get_iter_at_offset( out end, _end ); 83 | if( _add ) { 84 | editor.buffer.apply_tag_by_name( "selected", start, end ); 85 | } else { 86 | editor.buffer.remove_tag_by_name( "selected", start, end ); 87 | } 88 | } 89 | } 90 | 91 | private class UndoEditElement : UndoElement { 92 | private bool _insert; 93 | private int _start; 94 | private string _text; 95 | public UndoEditElement( bool insert, int start, string text ) { 96 | _insert = insert; 97 | _start = start; 98 | _text = text; 99 | } 100 | private void do_insert( Editor editor ) { 101 | TextIter start; 102 | editor.buffer.get_iter_at_offset( out start, _start ); 103 | editor.insert_text( ref start, _text ); 104 | } 105 | private void do_delete( Editor editor ) { 106 | TextIter start, end; 107 | editor.buffer.get_iter_at_offset( out start, _start ); 108 | editor.buffer.get_iter_at_offset( out end, (_start + _text.char_count()) ); 109 | editor.delete_text( ref start, ref end ); 110 | } 111 | public override void undo( Editor editor ) { 112 | if( _insert ) { 113 | do_delete( editor ); 114 | } else { 115 | do_insert( editor ); 116 | } 117 | } 118 | public override void redo( Editor editor ) { 119 | if( _insert ) { 120 | do_insert( editor ); 121 | } else { 122 | do_delete( editor ); 123 | } 124 | } 125 | public override bool mergeable( bool insert, int start, int end ) { 126 | if( _insert ) { 127 | return( insert && ((_start + _text.char_count()) == start) ); 128 | } else { 129 | return( (!insert && (end == _start)) || (insert && (start == _start)) ); 130 | } 131 | } 132 | } 133 | 134 | private Array _elements; 135 | 136 | public string name { set; get; default = ""; } 137 | public int id { set; get; default = -1; } 138 | 139 | /* Default constructor */ 140 | public UndoItem( string name ) { 141 | this.name = name; 142 | _elements = new Array(); 143 | } 144 | 145 | public void add_replacement( int start, string old_text, string new_text ) { 146 | var element = new UndoReplaceElement( start, old_text, new_text ); 147 | _elements.append_val( element ); 148 | } 149 | 150 | public void add_select( bool add, int start, int end ) { 151 | var element = new UndoSelectElement( add, start, end ); 152 | _elements.append_val( element ); 153 | } 154 | 155 | public void add_edit( bool insert, int start, string text ) { 156 | var element = new UndoEditElement( insert, start, text ); 157 | _elements.append_val( element ); 158 | } 159 | 160 | /* Causes the stored item to be put into the before state */ 161 | public void undo( Editor editor ) { 162 | for( int i=((int)_elements.length - 1); i>=0; i-- ) { 163 | _elements.index( i ).undo( editor ); 164 | } 165 | } 166 | 167 | /* Causes the stored item to be put into the after state */ 168 | public void redo( Editor editor ) { 169 | for( int i=0; i<_elements.length; i++ ) { 170 | _elements.index( i ).redo( editor ); 171 | } 172 | } 173 | 174 | /* 175 | Returns a hnalde to the last undo element if it is mergeable; otherwise, 176 | returns null. 177 | */ 178 | public bool mergeable( bool insert, int start, int end ) { 179 | if( _elements.length == 0 ) return( false ); 180 | var can_merge = _elements.index( _elements.length - 1 ).mergeable( insert, start, end ); 181 | return( can_merge ); 182 | } 183 | 184 | public string to_string() { 185 | return( "%s [%d]".printf( name, id ) ); 186 | } 187 | 188 | } 189 | -------------------------------------------------------------------------------- /src/functions/case/CaseCamel.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class CaseCamel : TextFunction { 23 | 24 | private Regex _re; 25 | 26 | /* Constructor */ 27 | public CaseCamel( bool custom = false ) { 28 | base( "case-camel", custom ); 29 | try { 30 | _re = new Regex( "[a-zA-Z]( )([a-z])" ); 31 | } catch( RegexError e ) {} 32 | } 33 | 34 | protected override string get_label0() { 35 | return( _( "Camel Case" ) ); 36 | } 37 | 38 | public override TextFunction copy( bool custom ) { 39 | return( new CaseCamel( custom ) ); 40 | } 41 | 42 | /* Perform the transformation */ 43 | public override string transform_text( string original, int cursor_pos ) { 44 | string[] parts; 45 | string orig = original.down(); 46 | if( CaseSnake.is_snake_case( original, out parts ) ) { 47 | orig = string.joinv( " ", parts ); 48 | } 49 | MatchInfo matches; 50 | while( _re.match( orig, 0, out matches ) ) { 51 | int start1, end1, start2, end2; 52 | matches.fetch_pos( 1, out start1, out end1 ); 53 | matches.fetch_pos( 2, out start2, out end2 ); 54 | orig = orig.splice( start2, end2, orig.slice( start2, end2 ).up() ).splice( start1, end1 ); 55 | } 56 | return( orig ); 57 | } 58 | 59 | /* 60 | Returns true if the given string is in camel case; otherwise, returns false. 61 | If true is returned, the camel case string is broken into its parts and returned 62 | for further processing. 63 | */ 64 | public static bool is_camel_case( string text, out string[] parts ) { 65 | var str = ""; 66 | var arr = new Array(); 67 | var last_lower = false; 68 | for( int i=0; i 1 ); 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/functions/case/CaseLower.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class CaseLower : TextFunction { 23 | 24 | /* Constructor */ 25 | public CaseLower( bool custom = false ) { 26 | base( "case-lower", custom ); 27 | } 28 | 29 | protected override string get_label0() { 30 | return( _( "Lower Case" ) ); 31 | } 32 | 33 | public override TextFunction copy( bool custom ) { 34 | return( new CaseLower( custom ) ); 35 | } 36 | 37 | /* Perform the transformation */ 38 | public override string transform_text( string original, int cursor_pos ) { 39 | string[] parts; 40 | string orig; 41 | if( CaseCamel.is_camel_case( original, out parts ) ) { 42 | orig = string.joinv( " ", parts ); 43 | } else if( CaseSnake.is_snake_case( original, out parts ) ) { 44 | orig = string.joinv( " ", parts ); 45 | } else { 46 | orig = original; 47 | } 48 | return( orig.down() ); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/functions/case/CaseRandom.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class CaseRandom : TextFunction { 23 | 24 | /* Constructor */ 25 | public CaseRandom( bool custom = false ) { 26 | base( "case-random", custom ); 27 | } 28 | 29 | protected override string get_label0() { 30 | return( _( "Random Case" ) ); 31 | } 32 | 33 | public override TextFunction copy( bool custom ) { 34 | return( new CaseRandom( custom ) ); 35 | } 36 | 37 | /* Perform the transformation */ 38 | public override string transform_text( string original, int cursor_pos ) { 39 | string[] parts; 40 | var str = ""; 41 | var rand = new Rand(); 42 | for( int i=0; i 20 | */ 21 | 22 | public class CaseSentence : TextFunction { 23 | 24 | private Regex _re; 25 | 26 | /* Constructor */ 27 | public CaseSentence( bool custom = false ) { 28 | base( "case-sentence", custom ); 29 | try { 30 | _re = new Regex( """(^\s*|[.!?]\s+)([a-z])""" ); 31 | } catch( RegexError e ) {} 32 | } 33 | 34 | protected override string get_label0() { 35 | return( _( "Sentence Case" ) ); 36 | } 37 | 38 | public override TextFunction copy( bool custom ) { 39 | return( new CaseSentence( custom ) ); 40 | } 41 | 42 | /* Perform the transformation */ 43 | public override string transform_text( string original, int cursor_pos ) { 44 | string[] parts; 45 | string orig = original.down(); 46 | if( CaseCamel.is_camel_case( original, out parts ) ) { 47 | orig = string.joinv( " ", parts ); 48 | } else if( CaseSnake.is_snake_case( original, out parts ) ) { 49 | orig = string.joinv( " ", parts ); 50 | } 51 | MatchInfo matches; 52 | int start, end; 53 | while( _re.match( orig, 0, out matches ) ) { 54 | matches.fetch_pos( 2, out start, out end ); 55 | orig = orig.splice( start, end, orig.slice( start, end ).up() ); 56 | } 57 | return( orig ); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/functions/case/CaseSnake.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class CaseSnake : TextFunction { 23 | 24 | private static Regex _is; 25 | 26 | /* Constructor */ 27 | public CaseSnake( bool custom = false ) { 28 | base( "case-snake", custom ); 29 | try { 30 | _is = new Regex( "^[a-z_]+$" ); 31 | } catch( RegexError e ) {} 32 | } 33 | 34 | protected override string get_label0() { 35 | return( _( "Snake Case" ) ); 36 | } 37 | 38 | public override TextFunction copy( bool custom ) { 39 | return( new CaseSnake( custom ) ); 40 | } 41 | 42 | /* Perform the transformation */ 43 | public override string transform_text( string original, int cursor_pos ) { 44 | string[] parts; 45 | string orig = original.down(); 46 | if( CaseCamel.is_camel_case( original, out parts ) ) { 47 | orig = string.joinv( " ", parts ); 48 | } 49 | return( orig.replace( " ", "_" ) ); 50 | } 51 | 52 | /* 53 | Returns true if the given string is in camel case; otherwise, returns false. 54 | If true is returned, the camel case string is broken into its parts and returned 55 | for further processing. 56 | */ 57 | public static bool is_snake_case( string text, out string[] parts ) { 58 | parts = {}; 59 | if( _is.match( text ) ) { 60 | parts = text.down().split( "_" ); 61 | return( true ); 62 | } 63 | return( false ); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/functions/case/CaseTitle.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class CaseTitle : TextFunction { 23 | 24 | private Regex _re; 25 | 26 | /* Constructor */ 27 | public CaseTitle( bool custom = false ) { 28 | base( "case-title", custom ); 29 | try { 30 | _re = new Regex( "(^|\\W)([a-z])" ); 31 | } catch( RegexError e ) {} 32 | } 33 | 34 | protected override string get_label0() { 35 | return( _( "Title Case" ) ); 36 | } 37 | 38 | public override TextFunction copy( bool custom ) { 39 | return( new CaseTitle( custom ) ); 40 | } 41 | 42 | /* Perform the transformation */ 43 | public override string transform_text( string original, int cursor_pos ) { 44 | string[] parts; 45 | string orig = original.down(); 46 | if( CaseCamel.is_camel_case( original, out parts ) ) { 47 | orig = string.joinv( " ", parts ); 48 | } else if( CaseSnake.is_snake_case( original, out parts ) ) { 49 | orig = string.joinv( " ", parts ); 50 | } 51 | MatchInfo matches; 52 | int start, end; 53 | while( _re.match( orig, 0, out matches ) ) { 54 | matches.fetch_pos( 2, out start, out end ); 55 | orig = orig.splice( start, end, orig.slice( start, end ).up() ); 56 | } 57 | return( orig ); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/functions/case/CaseUpper.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class CaseUpper : TextFunction { 23 | 24 | /* Constructor */ 25 | public CaseUpper( bool custom = false ) { 26 | base( "case-upper", custom ); 27 | } 28 | 29 | protected override string get_label0() { 30 | return( _( "Upper Case" ) ); 31 | } 32 | 33 | public override TextFunction copy( bool custom ) { 34 | return( new CaseUpper( custom ) ); 35 | } 36 | 37 | /* Perform the transformation */ 38 | public override string transform_text( string original, int cursor_pos ) { 39 | string[] parts; 40 | string orig = original.down(); 41 | if( CaseCamel.is_camel_case( original, out parts ) ) { 42 | orig = string.joinv( " ", parts ); 43 | } else if( CaseSnake.is_snake_case( original, out parts ) ) { 44 | orig = string.joinv( " ", parts ); 45 | } 46 | return( orig.up() ); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/functions/case/meson.build: -------------------------------------------------------------------------------- 1 | sources += files( 2 | 3 | 'CaseCamel.vala', 4 | 'CaseLower.vala', 5 | 'CaseRandom.vala', 6 | 'CaseSentence.vala', 7 | 'CaseSnake.vala', 8 | 'CaseTitle.vala', 9 | 'CaseUpper.vala' 10 | 11 | ) 12 | -------------------------------------------------------------------------------- /src/functions/convert/ConvertBase64.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class ConvertBase64 : TextFunction { 25 | 26 | /* Constructor */ 27 | public ConvertBase64( bool custom = false ) { 28 | base( "convert-base64", custom, FunctionDirection.LEFT_TO_RIGHT ); 29 | } 30 | 31 | protected override string get_label0() { 32 | return( _( "Encode To Base64" ) ); 33 | } 34 | 35 | protected override string get_label1() { 36 | return( _( "Decode From Base64" ) ); 37 | } 38 | 39 | public override TextFunction copy( bool custom ) { 40 | var fn = new ConvertBase64( custom ); 41 | fn.direction = direction; 42 | return( fn ); 43 | } 44 | 45 | /* Perform the transformation */ 46 | public override string transform_text( string original, int cursor_pos ) { 47 | string str; 48 | if( direction == FunctionDirection.LEFT_TO_RIGHT ) { 49 | str = Base64.encode( (uchar[])original.data ); 50 | } else { 51 | str = (string)Base64.decode( original ); 52 | } 53 | return( str.validate() ? str : original ); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/functions/convert/ConvertChecksum.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class ConvertChecksum : TextFunction { 25 | 26 | public enum EncodeType { 27 | MD5, 28 | SHA1, 29 | SHA256, 30 | SHA384, 31 | SHA512, 32 | LENGTH; 33 | 34 | public string label() { 35 | switch( this ) { 36 | case MD5 : return( "MD5" ); 37 | case SHA1 : return( "SHA-1" ); 38 | case SHA256 : return( "SHA-256" ); 39 | case SHA384 : return( "SHA-384" ); 40 | case SHA512 : return( "SHA-512" ); 41 | default : assert_not_reached(); 42 | } 43 | } 44 | 45 | public string to_string() { 46 | switch( this ) { 47 | case MD5 : return( "md5" ); 48 | case SHA1 : return( "sha1" ); 49 | case SHA256 : return( "sha256" ); 50 | case SHA384 : return( "sha384" ); 51 | case SHA512 : return( "sha512" ); 52 | default : assert_not_reached(); 53 | } 54 | } 55 | 56 | public static EncodeType parse( string val ) { 57 | switch( val ) { 58 | case "md5" : return( MD5 ); 59 | case "sha1" : return( SHA1 ); 60 | case "sha256" : return( SHA256 ); 61 | case "sha384" : return( SHA384 ); 62 | case "sha512" : return( SHA512 ); 63 | default : assert_not_reached(); 64 | } 65 | } 66 | 67 | public ChecksumType type() { 68 | switch( this ) { 69 | case MD5 : return( ChecksumType.MD5 ); 70 | case SHA1 : return( ChecksumType.SHA1 ); 71 | case SHA256 : return( ChecksumType.SHA256 ); 72 | case SHA384 : return( ChecksumType.SHA384 ); 73 | case SHA512 : return( ChecksumType.SHA512 ); 74 | default : assert_not_reached(); 75 | } 76 | } 77 | } 78 | 79 | private EncodeType _type = EncodeType.MD5; 80 | 81 | /* Constructor */ 82 | public ConvertChecksum( bool custom = false ) { 83 | base( "convert-checksum", custom ); 84 | } 85 | 86 | protected override string get_label0() { 87 | return( _( "Encode as %s checksum" ).printf( _type.label() ) ); 88 | } 89 | 90 | public override TextFunction copy( bool custom ) { 91 | return( new ConvertChecksum( custom ) ); 92 | } 93 | 94 | public override bool matches( TextFunction function ) { 95 | if( base.matches( function ) ) { 96 | var fn = (ConvertChecksum)function; 97 | return( _type == fn._type ); 98 | } 99 | return( false ); 100 | } 101 | 102 | public override bool settings_available() { 103 | return( true ); 104 | } 105 | 106 | /* Populates the given popover with the settings */ 107 | public override void add_settings( Grid grid ) { 108 | 109 | add_menubutton_setting( grid, 1, _( "Checksum Type" ), _type, EncodeType.LENGTH, (value) => { 110 | var type = (EncodeType)value; 111 | return( type.label() ); 112 | }, (value) => { 113 | _type = (EncodeType)value; 114 | update_button_label(); 115 | }); 116 | 117 | } 118 | 119 | /* Perform the transformation */ 120 | public override string transform_text( string original, int cursor_pos ) { 121 | return( Checksum.compute_for_string( _type.type(), original ) ); 122 | } 123 | 124 | public override Xml.Node* save() { 125 | Xml.Node* node = base.save(); 126 | node->set_prop( "type", _type.to_string() ); 127 | return( node ); 128 | } 129 | 130 | public override void load( Xml.Node* node, TextFunctions functions ) { 131 | base.load( node, functions ); 132 | var t = node->get_prop( "type" ); 133 | if( t != null ) { 134 | _type = EncodeType.parse( t ); 135 | } 136 | update_button_label(); 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /src/functions/convert/ConvertHardWrap.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class ConvertHardWrap : TextFunction { 25 | 26 | private enum HardWrapType { 27 | CHAR, 28 | WORD, 29 | LENGTH; 30 | 31 | public string label() { 32 | switch( this ) { 33 | case CHAR : return( _( "Characters" ) ); 34 | case WORD : return( _( "Words" ) ); 35 | default : assert_not_reached(); 36 | } 37 | } 38 | 39 | public string to_string() { 40 | switch( this ) { 41 | case CHAR : return( "char" ); 42 | case WORD : return( "word" ); 43 | default : assert_not_reached(); 44 | } 45 | } 46 | 47 | public static HardWrapType parse( string val ) { 48 | switch( val ) { 49 | case "char" : return( CHAR ); 50 | case "word" : return( WORD ); 51 | default : assert_not_reached(); 52 | } 53 | } 54 | } 55 | 56 | private int _col_width = 80; 57 | private HardWrapType _wrap_type = HardWrapType.WORD; 58 | 59 | /* Constructor */ 60 | public ConvertHardWrap( bool custom = false ) { 61 | base( "convert-hard-wrap", custom ); 62 | } 63 | 64 | protected override string get_label0() { 65 | return( _( "Hard Wrap At %d %s" ).printf( _col_width, _wrap_type.label() ) ); 66 | } 67 | 68 | public override TextFunction copy( bool custom ) { 69 | var fn = new ConvertHardWrap( custom ); 70 | fn._col_width = _col_width; 71 | fn._wrap_type = _wrap_type; 72 | return( fn ); 73 | } 74 | 75 | public override bool matches( TextFunction function ) { 76 | if( base.matches( function ) ) { 77 | var fn = (ConvertHardWrap)function; 78 | return( 79 | (_col_width == fn._col_width) && 80 | (_wrap_type == fn._wrap_type) 81 | ); 82 | } 83 | return( false ); 84 | } 85 | 86 | public override bool settings_available() { 87 | return( true ); 88 | } 89 | 90 | /* Populates the given popover with the settings */ 91 | public override void add_settings( Grid grid ) { 92 | 93 | add_range_setting( grid, 0, _( "Column Width" ), 20, 150, 5, _col_width, (value) => { 94 | _col_width = value; 95 | update_button_label(); 96 | }); 97 | 98 | add_menubutton_setting( grid, 1, _( "Wrap Type" ), _wrap_type, HardWrapType.LENGTH, (value) => { 99 | var type = (HardWrapType)value; 100 | return( type.label() ); 101 | }, (value) => { 102 | _wrap_type = (HardWrapType)value; 103 | update_button_label(); 104 | }); 105 | 106 | } 107 | 108 | /* Perform the transformation */ 109 | public override string transform_text( string original, int cursor_pos ) { 110 | 111 | var lines = original.split( "\n" ); 112 | var str = ""; 113 | 114 | foreach( string line in lines ) { 115 | switch( _wrap_type ) { 116 | case HardWrapType.CHAR : str += char_wrap( line ); break; 117 | case HardWrapType.WORD : str += word_wrap( line ); break; 118 | } 119 | } 120 | 121 | return( str.chomp() ); 122 | 123 | } 124 | 125 | private string char_wrap( string line ) { 126 | var ln = line; 127 | var str = ""; 128 | while( ln.char_count() > _col_width ) { 129 | str += ln.substring( 0, _col_width ) + "\n"; 130 | ln = ln.substring( _col_width ); 131 | } 132 | return( str + ln + "\n" ); 133 | } 134 | 135 | private string word_wrap( string line ) { 136 | var words = Regex.split_simple( """\s""", line ); 137 | var str = ""; 138 | var ln = ""; 139 | var ws_idx = 0; 140 | for( int i=0; iset_prop( "column-width", _col_width.to_string() ); 158 | node->set_prop( "wrap-type", _wrap_type.to_string() ); 159 | return( node ); 160 | } 161 | 162 | public override void load( Xml.Node* node, TextFunctions functions ) { 163 | base.load( node, functions ); 164 | var cw = node->get_prop( "column-width" ); 165 | if( cw != null ) { 166 | _col_width = int.parse( cw ); 167 | } 168 | var wt = node->get_prop( "wrap-type" ); 169 | if( wt != null ) { 170 | _wrap_type = HardWrapType.parse( wt ); 171 | } 172 | update_button_label(); 173 | } 174 | 175 | } 176 | -------------------------------------------------------------------------------- /src/functions/convert/ConvertROT13.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gdk; 23 | 24 | public class ConvertROT13 : TextFunction { 25 | 26 | /* Constructor */ 27 | public ConvertROT13( bool custom = false ) { 28 | base( "convert-rot13", custom ); 29 | } 30 | 31 | protected override string get_label0() { 32 | return( _( "ROT 13" ) ); 33 | } 34 | 35 | public override TextFunction copy( bool custom ) { 36 | return( new ConvertROT13( custom ) ); 37 | } 38 | 39 | /* Perform the transformation */ 40 | public override string transform_text( string original, int cursor_pos ) { 41 | var str = ""; 42 | for( int i=0; i 20 | */ 21 | 22 | using Xml; 23 | 24 | public class Indent : TextFunction { 25 | 26 | /* Constructor */ 27 | public Indent( bool custom = false ) { 28 | base( "indent", custom ); 29 | } 30 | 31 | protected override string get_label0() { 32 | return( _( "Indent One Level" ) ); 33 | } 34 | 35 | public override TextFunction copy( bool custom ) { 36 | return( new Indent( custom ) ); 37 | } 38 | 39 | /* Perform the transformation */ 40 | public override string transform_text( string original, int cursor_pos ) { 41 | var lines = original.split( "\n" ); 42 | for( int i=0; i 20 | */ 21 | 22 | using Xml; 23 | 24 | public class IndentXML : TextFunction { 25 | 26 | /* Constructor */ 27 | public IndentXML( bool custom = false ) { 28 | base( "indent-xml", custom ); 29 | } 30 | 31 | protected override string get_label0() { 32 | return( _( "Indent XML" ) ); 33 | } 34 | 35 | public override TextFunction copy( bool custom ) { 36 | return( new IndentXML( custom ) ); 37 | } 38 | 39 | private bool next_char_is( string str, int start, string match ) { 40 | var start_pos = str.index_of_nth_char( start ); 41 | for( int i=start; i" : 84 | if( in_com && ((fdash_pos + 2) == pos) ) { 85 | in_com = false; 86 | } else if( in_tag ) { 87 | if( (begin_pos + 1) == slash_pos ) { // If this is an closing tag 88 | line_indent--; 89 | if( !next_char_is( orig, (i + 1), "\n" ) ) { 90 | var ins_index = orig.index_of_nth_char( i + 1 ); 91 | orig = orig.splice( ins_index, ins_index, "\n" ); 92 | } 93 | } else if( ((slash_pos + 1) != pos) && ((ques_pos + 1) != pos) ) { // If this is an opening tag 94 | line_indent++; 95 | start_found = true; 96 | if( next_char_is( orig, (i + 1), "<" ) && 97 | !next_char_is( orig, (i + 1), " 0 ) { 159 | str += string.nfill( indent, '\t' ); 160 | } 161 | indent += line_indent; 162 | } else { 163 | indent += line_indent; 164 | if( indent > 0 ) { 165 | str += string.nfill( indent, '\t' ); 166 | } 167 | } 168 | str += line + "\n"; 169 | line = ""; 170 | line_indent = 0; 171 | saw_first = false; 172 | start_found = false; 173 | break; 174 | default : 175 | saw_first = true; 176 | break; 177 | } 178 | if( saw_first ) { 179 | line += c; 180 | } 181 | pos++; 182 | } 183 | if( (indent + line_indent) > 0 ) { 184 | str += string.nfill( (indent + line_indent), '\t' ); 185 | } 186 | str += line; 187 | return( str ); 188 | } 189 | 190 | } 191 | -------------------------------------------------------------------------------- /src/functions/indent/Unindent.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Xml; 23 | 24 | public class Unindent : TextFunction { 25 | 26 | /* Constructor */ 27 | public Unindent( bool custom = false ) { 28 | base( "unindent", false ); 29 | } 30 | 31 | protected override string get_label0() { 32 | return( _( "Unindent One Level" ) ); 33 | } 34 | 35 | public override TextFunction copy( bool custom ) { 36 | return( new Unindent( custom ) ); 37 | } 38 | 39 | /* Perform the transformation */ 40 | public override string transform_text( string original, int cursor_pos ) { 41 | var lines = original.split( "\n" ); 42 | for( int i=0; i 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class InsertFile : TextFunction { 25 | 26 | private MainWindow _win; 27 | private string _filename = ""; 28 | 29 | /* Constructor */ 30 | public InsertFile( MainWindow win, bool custom = false ) { 31 | base( "insert-file", custom ); 32 | _win = win; 33 | } 34 | 35 | protected override string get_label0() { 36 | return( _( "Insert File Text" ) ); 37 | } 38 | 39 | public override TextFunction copy( bool custom ) { 40 | return( new InsertFile( _win, custom ) ); 41 | } 42 | 43 | private void insert_selected_file( Editor editor ) { 44 | 45 | var dialog = new FileChooserNative( _( "Insert File" ), _win, FileChooserAction.OPEN, _( "Open" ), _( "Cancel" ) ); 46 | 47 | dialog.response.connect((id) => { 48 | if( id == ResponseType.ACCEPT ) { 49 | _filename = dialog.get_file().get_path(); 50 | var undo_item = new UndoItem( label ); 51 | insert_file( editor, undo_item ); 52 | editor.undo_buffer.add_item( undo_item ); 53 | } 54 | dialog.destroy(); 55 | }); 56 | 57 | dialog.show(); 58 | 59 | } 60 | 61 | private string? get_file_contents( string filename ) { 62 | 63 | var file = File.new_for_path( filename ); 64 | 65 | try { 66 | uint8[] contents; 67 | file.load_contents( null, out contents, null ); 68 | return( (string)contents ); 69 | } catch( Error e ) { 70 | _win.show_error( e.message ); 71 | } 72 | 73 | return( null ); 74 | 75 | } 76 | 77 | public override void run( Editor editor, UndoItem undo_item ) { 78 | insert_file( editor, undo_item ); 79 | } 80 | 81 | public override void launch( Editor editor ) { 82 | if( custom ) { 83 | insert_file( editor, null ); 84 | } else { 85 | insert_selected_file( editor ); 86 | } 87 | } 88 | 89 | private Box create_widget( Editor editor ) { 90 | 91 | var chooser = new Button.with_label( _( "Insert File" ) ); 92 | chooser.clicked.connect(() => { 93 | insert_selected_file( editor ); 94 | }); 95 | 96 | var box = new Box( Orientation.HORIZONTAL, 5 ); 97 | box.append( chooser ); 98 | 99 | return( box ); 100 | 101 | } 102 | 103 | public override Box? get_widget( Editor editor ) { 104 | return( create_widget( editor ) ); 105 | } 106 | 107 | private void insert_file( Editor editor, UndoItem? undo_item ) { 108 | 109 | var contents = get_file_contents( _filename ); 110 | if( contents == null ) return; 111 | 112 | TextIter cursor; 113 | 114 | editor.buffer.get_iter_at_mark( out cursor, editor.buffer.get_insert() ); 115 | editor.replace_text( cursor, cursor, contents, undo_item ); 116 | 117 | } 118 | 119 | public override Xml.Node* save() { 120 | Xml.Node* node = base.save(); 121 | node->set_prop( "filename", _filename ); 122 | return( node ); 123 | } 124 | 125 | public override void load( Xml.Node* node, TextFunctions functions ) { 126 | base.load( node, functions ); 127 | string? f = node->get_prop( "filename" ); 128 | if( f != null ) { 129 | _filename = f; 130 | } 131 | 132 | } 133 | 134 | } 135 | 136 | -------------------------------------------------------------------------------- /src/functions/insert/InsertLineNumbers.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class InsertLineNumbers : TextFunction { 25 | 26 | private string _separator; 27 | private bool _pad; 28 | private bool _skip_blanks; 29 | 30 | /* Constructor */ 31 | public InsertLineNumbers( bool custom = false ) { 32 | base( "insert-line-numbers", custom ); 33 | _separator = "."; 34 | _pad = false; 35 | _skip_blanks = true; 36 | } 37 | 38 | protected override string get_label0() { 39 | return( _( "Insert Line Numbers" ) ); 40 | } 41 | 42 | public override TextFunction copy( bool custom ) { 43 | var fn = new InsertLineNumbers( custom ); 44 | fn._separator = _separator; 45 | fn._pad = _pad; 46 | fn._skip_blanks = _skip_blanks; 47 | return( fn ); 48 | } 49 | 50 | public override bool matches( TextFunction function ) { 51 | if( base.matches( function ) ) { 52 | var func = (InsertLineNumbers)function; 53 | return( 54 | (_separator == func._separator) && 55 | (_pad == func._pad) && 56 | (_skip_blanks == func._skip_blanks) 57 | ); 58 | } 59 | return( false ); 60 | } 61 | 62 | /* Perform the transformation */ 63 | public override string transform_text( string original, int cursor_pos ) { 64 | var lines = original.split( "\n" ); 65 | var num_lines = lines.length; 66 | var linenum = 1; 67 | for( int i=0; i { 89 | _separator = value; 90 | }); 91 | 92 | add_bool_setting( grid, 1, _( "Add Padding" ), _pad, (value) => { 93 | _pad = value; 94 | }); 95 | 96 | add_bool_setting( grid, 2, _( "Skip Blank Lines" ), _skip_blanks, (value) => { 97 | _skip_blanks = value; 98 | }); 99 | 100 | } 101 | 102 | public override Xml.Node* save() { 103 | Xml.Node* node = base.save(); 104 | node->set_prop( "separator", _separator ); 105 | node->set_prop( "pad", _pad.to_string() ); 106 | node->set_prop( "skip_blanks", _skip_blanks.to_string() ); 107 | return( node ); 108 | } 109 | 110 | public override void load( Xml.Node* node, TextFunctions functions ) { 111 | base.load( node, functions ); 112 | var s = node->get_prop( "separator" ); 113 | if( s != null ) { 114 | _separator = s; 115 | } 116 | var p = node->get_prop( "pad" ); 117 | if( p != null ) { 118 | _pad = bool.parse( p ); 119 | } 120 | var sb = node->get_prop( "skip_blanks" ); 121 | if( sb != null ) { 122 | _skip_blanks = bool.parse( sb ); 123 | } 124 | update_button_label(); 125 | } 126 | 127 | } 128 | 129 | -------------------------------------------------------------------------------- /src/functions/insert/InsertURL.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class InsertURL : TextFunction { 25 | 26 | private MainWindow _win; 27 | private string _url = ""; 28 | 29 | /* Constructor */ 30 | public InsertURL( MainWindow win, bool custom = false ) { 31 | base( "insert-url", custom ); 32 | _win = win; 33 | } 34 | 35 | protected override string get_label0() { 36 | return( _( "Insert URL Content" ) ); 37 | } 38 | 39 | public override TextFunction copy( bool custom ) { 40 | var tf = new InsertURL( _win, custom ); 41 | tf._url = _url; 42 | return( tf ); 43 | } 44 | 45 | public override bool matches( TextFunction function ) { 46 | if( base.matches( function ) ) { 47 | var func = (InsertURL)function; 48 | return( _url == func._url ); 49 | } 50 | return( false ); 51 | } 52 | 53 | private string? get_url_contents( string url ) { 54 | 55 | var file = File.new_for_uri( url ); 56 | 57 | try { 58 | uint8[] contents; 59 | file.load_contents( null, out contents, null ); 60 | return( (string)contents ); 61 | } catch( Error e ) { 62 | stdout.printf( "Unable to get URL contents\n" ); 63 | _win.show_error( e.message ); 64 | } 65 | 66 | return( null ); 67 | 68 | } 69 | 70 | public override void run( Editor editor, UndoItem undo_item ) { 71 | insert_url( editor, undo_item ); 72 | } 73 | 74 | public override void launch( Editor editor ) { 75 | if( custom ) { 76 | insert_url( editor, null ); 77 | } else { 78 | Box box; 79 | Entry entry; 80 | create_widget( editor, out box, out entry ); 81 | _win.add_widget( box, entry ); 82 | } 83 | } 84 | 85 | private Box create_widget( Editor editor, out Box box, out Entry focus ) { 86 | 87 | var entry = new Entry() { 88 | halign = Align.FILL, 89 | hexpand = true, 90 | placeholder_text = _( "Enter URL" ), 91 | tooltip_text = _( "Enter URL" ) 92 | }; 93 | 94 | if( custom ) { 95 | 96 | entry.text = _url; 97 | entry.changed.connect(() => { 98 | _url = entry.text; 99 | custom_changed(); 100 | }); 101 | 102 | } else { 103 | 104 | entry.activate.connect(() => { 105 | _url = entry.text; 106 | var undo_item = new UndoItem( label ); 107 | insert_url( editor, undo_item ); 108 | editor.undo_buffer.add_item( undo_item ); 109 | _win.remove_widget(); 110 | }); 111 | 112 | handle_widget_escape( entry, _win ); 113 | 114 | focus = entry; 115 | 116 | } 117 | 118 | box = new Box( Orientation.HORIZONTAL, 5 ); 119 | box.append( entry ); 120 | 121 | return( box ); 122 | 123 | } 124 | 125 | public override Box? get_widget( Editor editor ) { 126 | Box box; 127 | Entry entry; 128 | create_widget( editor, out box, out entry ); 129 | return( box ); 130 | } 131 | 132 | private void insert_url( Editor editor, UndoItem? undo_item ) { 133 | 134 | var contents = get_url_contents( _url ); 135 | if( contents == null ) return; 136 | 137 | TextIter cursor; 138 | 139 | editor.buffer.get_iter_at_mark( out cursor, editor.buffer.get_insert() ); 140 | editor.replace_text( cursor, cursor, contents, undo_item ); 141 | 142 | } 143 | 144 | public override Xml.Node* save() { 145 | Xml.Node* node = base.save(); 146 | node->set_prop( "url", _url ); 147 | return( node ); 148 | } 149 | 150 | public override void load( Xml.Node* node, TextFunctions functions ) { 151 | base.load( node, functions ); 152 | string? u = node->get_prop( "url" ); 153 | if( u != null ) { 154 | _url = u; 155 | } 156 | 157 | } 158 | 159 | } 160 | 161 | -------------------------------------------------------------------------------- /src/functions/insert/meson.build: -------------------------------------------------------------------------------- 1 | sources += files( 2 | 3 | 'InsertFile.vala', 4 | 'InsertLineNumbers.vala', 5 | 'InsertLoremIpsum.vala', 6 | 'InsertText.vala', 7 | 'InsertURL.vala' 8 | 9 | ) 10 | -------------------------------------------------------------------------------- /src/functions/markdown/MarkdownReferences.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | using Gee; 24 | 25 | public class MarkdownReferences : TextFunction { 26 | 27 | private Regex _link_re; 28 | private Regex _ref_re; 29 | private int _ref_num; 30 | private Array _links; 31 | private HashMap _link_to_ref; 32 | private HashMap _old_to_new; 33 | 34 | /* Constructor */ 35 | public MarkdownReferences( bool custom = false ) { 36 | base( "markdown-references", custom ); 37 | try { 38 | _link_re = new Regex( """\[[^]]*\](\(([^\)]+)\)|\[([^]]+)\])""" ); 39 | _ref_re = new Regex( """^\[(.*?)\]:\s+(.*)$""" ); 40 | } catch( RegexError e ) {} 41 | } 42 | 43 | protected override string get_label0() { 44 | return( _( "Generate References" ) ); 45 | } 46 | 47 | public override TextFunction copy( bool custom ) { 48 | return( new MarkdownReferences( custom ) ); 49 | } 50 | 51 | public override void launch( Editor editor ) { 52 | 53 | _ref_num = 1; 54 | _links = new Array(); 55 | _link_to_ref = new HashMap(); 56 | _old_to_new = new HashMap(); 57 | 58 | var str = editor.buffer.text; 59 | 60 | str = parse_refs( str ); 61 | str = parse_links( str ); 62 | str = append_references( str ).chomp(); 63 | 64 | TextIter start, end; 65 | editor.buffer.get_bounds( out start, out end ); 66 | 67 | var undo_item = new UndoItem( name ); 68 | editor.replace_text( start, end, str, undo_item ); 69 | editor.undo_buffer.add_item( undo_item ); 70 | 71 | } 72 | 73 | private string parse_refs( string text ) { 74 | 75 | MatchInfo match; 76 | var str = ""; 77 | 78 | foreach( string line in text.split( "\n" ) ) { 79 | if( _ref_re.match( line, 0, out match ) ) { 80 | var reference = match.fetch( 1 ).strip(); 81 | var link = match.fetch( 2 ).strip(); 82 | _links.append_val( link ); 83 | _link_to_ref.@set( link, _ref_num.to_string() ); 84 | _old_to_new.@set( reference, _ref_num.to_string() ); 85 | _ref_num++; 86 | } else { 87 | str += line + "\n"; 88 | } 89 | } 90 | 91 | return( str.strip() ); 92 | 93 | } 94 | 95 | private string parse_links( string text ) { 96 | 97 | MatchInfo match; 98 | int start = 0; 99 | int end; 100 | var str = ""; 101 | 102 | try { 103 | foreach( string line in text.split( "\n" ) ) { 104 | start = 0; 105 | while( _link_re.match_full( line, -1, start, 0, out match ) ) { 106 | if( match.fetch_pos( 2, out start, out end ) && (start != -1) ) { 107 | var link = line.slice( start, end ).strip(); 108 | if( !_link_to_ref.has_key( link ) ) { 109 | _links.append_val( link ); 110 | _link_to_ref.@set( link, _ref_num.to_string() ); 111 | match.fetch_pos( 1, out start, out end ); 112 | line = line.splice( start, end, "[" + _ref_num.to_string() + "]" ); 113 | _ref_num++; 114 | } 115 | } else if( match.fetch_pos( 3, out start, out end ) && (start != -1) ) { 116 | var reference = line.slice( start, end ).strip(); 117 | if( _old_to_new.has_key( reference ) ) { 118 | match.fetch_pos( 1, out start, out end ); 119 | line = line.splice( start, end, "[" + _old_to_new.@get( reference ) + "]" ); 120 | } 121 | } 122 | } 123 | str += line + "\n"; 124 | } 125 | } catch( RegexError e ) {} 126 | 127 | return( str ); 128 | 129 | } 130 | 131 | private string append_references( string text ) { 132 | 133 | if( _ref_num == 1 ) return( text ); 134 | 135 | /* Append the references to the end of the text */ 136 | var str = text + "\n"; 137 | for( int i=1; i<_ref_num; i++ ) { 138 | str += "[" + i.to_string() + "]: " + _links.index( i-1 ) + "\n"; 139 | } 140 | 141 | return( str ); 142 | 143 | } 144 | 145 | } 146 | 147 | 148 | -------------------------------------------------------------------------------- /src/functions/markdown/MarkdownTaskAdd.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public enum MarkdownTaskApplyType { 25 | LINE, 26 | PARAGRAPH, 27 | LENGTH; 28 | 29 | public string label() { 30 | switch( this ) { 31 | case LINE : return( _( "Line" ) ); 32 | case PARAGRAPH : return( _( "Paragraph" ) ); 33 | default : assert_not_reached(); 34 | } 35 | } 36 | 37 | public string to_string() { 38 | switch( this ) { 39 | case LINE : return( "line" ); 40 | case PARAGRAPH : return( "paragraph" ); 41 | default : assert_not_reached(); 42 | } 43 | } 44 | 45 | public static MarkdownTaskApplyType parse( string val ) { 46 | switch( val ) { 47 | case "line" : return( LINE ); 48 | case "paragraph" : return( PARAGRAPH ); 49 | default : assert_not_reached(); 50 | } 51 | } 52 | } 53 | 54 | public class MarkdownTaskAdd : TextFunction { 55 | 56 | 57 | private Regex _re; 58 | private MarkdownTaskApplyType _apply = MarkdownTaskApplyType.LINE; 59 | 60 | /* Constructor */ 61 | public MarkdownTaskAdd( bool custom = false ) { 62 | base( "markdown-task-add", custom ); 63 | try { 64 | _re = new Regex( """^\s*\[[ xX]\] (.*)$""" ); 65 | } catch( RegexError e ) {} 66 | } 67 | 68 | protected override string get_label0() { 69 | return( _( "Add Markdown Tasks" ) ); 70 | } 71 | 72 | public override TextFunction copy( bool custom ) { 73 | var tf = new MarkdownTaskAdd( custom ); 74 | tf._apply = _apply; 75 | return( tf ); 76 | } 77 | 78 | public override bool matches( TextFunction function ) { 79 | return( base.matches( function ) && (_apply == ((MarkdownTaskAdd)function)._apply) ); 80 | } 81 | 82 | public override bool settings_available() { 83 | return( true ); 84 | } 85 | 86 | /* Populates the given popover with the settings */ 87 | public override void add_settings( Grid grid ) { 88 | add_menubutton_setting( grid, 0, _( "Apply To" ), _apply, MarkdownTaskApplyType.LENGTH, (value) => { 89 | var apply = (MarkdownTaskApplyType)value; 90 | return( apply.label() ); 91 | }, (value) => { 92 | _apply = (MarkdownTaskApplyType)value; 93 | }); 94 | } 95 | 96 | public override Xml.Node* save() { 97 | Xml.Node* node = base.save(); 98 | node->set_prop( "apply", _apply.to_string() ); 99 | return( node ); 100 | } 101 | 102 | public override void load( Xml.Node* node, TextFunctions functions ) { 103 | base.load( node, functions ); 104 | var a = node->get_prop( "apply" ); 105 | if( a != null ) { 106 | _apply = MarkdownTaskApplyType.parse( a ); 107 | } 108 | } 109 | 110 | public override string transform_text( string original, int cursor_pos ) { 111 | var str = ""; 112 | var first = true; 113 | var add = false; 114 | MatchInfo match; 115 | foreach( string line in original.split( "\n" ) ) { 116 | if( first ) { 117 | first = false; 118 | } else { 119 | str += "\n"; 120 | } 121 | if( line.strip() == "" ) { 122 | add = false; 123 | } else if( !_re.match( line, 0, out match ) ) { 124 | if( !add ) { 125 | str += "[ ] "; 126 | } else if( add ) { 127 | str += " "; 128 | } 129 | add = (_apply == MarkdownTaskApplyType.PARAGRAPH); 130 | } 131 | str += line; 132 | } 133 | return( str ); 134 | } 135 | 136 | } 137 | 138 | 139 | -------------------------------------------------------------------------------- /src/functions/markdown/MarkdownTaskComplete.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class MarkdownTaskComplete : TextFunction { 25 | 26 | Regex _re; 27 | 28 | /* Constructor */ 29 | public MarkdownTaskComplete( bool custom = false ) { 30 | base( "markdown-task-complete", custom ); 31 | try { 32 | _re = new Regex( """^(\s*)\[ \] (.*)$""" ); 33 | } catch( RegexError e ) {} 34 | } 35 | 36 | protected override string get_label0() { 37 | return( _( "Mark Markdown Tasks As Complete" ) ); 38 | } 39 | 40 | public override TextFunction copy( bool custom ) { 41 | return( new MarkdownTaskComplete( custom ) ); 42 | } 43 | 44 | public override string transform_text( string original, int cursor_pos ) { 45 | var str = ""; 46 | var first = true; 47 | MatchInfo match; 48 | foreach( string line in original.split( "\n" ) ) { 49 | if( first ) { 50 | first = false; 51 | } else { 52 | str += "\n"; 53 | } 54 | if( _re.match( line, 0, out match ) ) { 55 | str += match.fetch( 1 ) + "[x] " + match.fetch( 2 ); 56 | } else { 57 | str += line; 58 | } 59 | } 60 | return( str ); 61 | } 62 | 63 | } 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/functions/markdown/MarkdownTaskDelete.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class MarkdownTaskDelete : TextFunction { 25 | 26 | Regex _re; 27 | MarkdownTaskApplyType _apply = MarkdownTaskApplyType.LINE; 28 | 29 | /* Constructor */ 30 | public MarkdownTaskDelete( bool custom = false ) { 31 | base( "markdown-task-delete", custom ); 32 | try { 33 | _re = new Regex( """^\s*\[[ xX]\] (.*)$""" ); 34 | } catch( RegexError e ) {} 35 | } 36 | 37 | protected override string get_label0() { 38 | return( _( "Remove Markdown Tasks" ) ); 39 | } 40 | 41 | public override TextFunction copy( bool custom ) { 42 | var tf = new MarkdownTaskDelete( custom ); 43 | tf._apply = _apply; 44 | return( tf ); 45 | } 46 | 47 | public override bool matches( TextFunction function ) { 48 | return( base.matches( function ) && (_apply == ((MarkdownTaskDelete)function)._apply) ); 49 | } 50 | 51 | public override bool settings_available() { 52 | return( true ); 53 | } 54 | 55 | /* Populates the given popover with the settings */ 56 | public override void add_settings( Grid grid ) { 57 | add_menubutton_setting( grid, 0, _( "Apply To" ), _apply, MarkdownTaskApplyType.LENGTH, (value) => { 58 | var apply = (MarkdownTaskApplyType)value; 59 | return( apply.label() ); 60 | }, (value) => { 61 | _apply = (MarkdownTaskApplyType)value; 62 | }); 63 | } 64 | 65 | public override Xml.Node* save() { 66 | Xml.Node* node = base.save(); 67 | node->set_prop( "apply", _apply.to_string() ); 68 | return( node ); 69 | } 70 | 71 | public override void load( Xml.Node* node, TextFunctions functions ) { 72 | base.load( node, functions ); 73 | var a = node->get_prop( "apply" ); 74 | if( a != null ) { 75 | _apply = MarkdownTaskApplyType.parse( a ); 76 | } 77 | } 78 | 79 | public override string transform_text( string original, int cursor_pos ) { 80 | var str = ""; 81 | var first = true; 82 | var del = false; 83 | MatchInfo match; 84 | foreach( string line in original.split( "\n" ) ) { 85 | if( first ) { 86 | first = false; 87 | } else { 88 | str += "\n"; 89 | } 90 | if( _re.match( line, 0, out match ) ) { 91 | str += match.fetch( 1 ); 92 | del = (_apply == MarkdownTaskApplyType.PARAGRAPH); 93 | } else if( line.strip() == "" ) { 94 | del = false; 95 | str += line; 96 | } else if( del && (line.substring( 0, 4 ) == " ") ) { 97 | str += line.substring( line.index_of_nth_char( 4 ) ); 98 | } else { 99 | str += line; 100 | } 101 | } 102 | return( str ); 103 | } 104 | 105 | } 106 | 107 | 108 | -------------------------------------------------------------------------------- /src/functions/markdown/MarkdownTaskIncomplete.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class MarkdownTaskIncomplete : TextFunction { 25 | 26 | Regex _re; 27 | 28 | /* Constructor */ 29 | public MarkdownTaskIncomplete( bool custom = false ) { 30 | base( "markdown-task-incomplete", custom ); 31 | try { 32 | _re = new Regex( """^(\s*)\[[xX]\] (.*)$""" ); 33 | } catch( RegexError e ) {} 34 | } 35 | 36 | protected override string get_label0() { 37 | return( _( "Mark Markdown Tasks As Incomplete" ) ); 38 | } 39 | 40 | public override TextFunction copy( bool custom ) { 41 | return( new MarkdownTaskIncomplete( custom ) ); 42 | } 43 | 44 | public override string transform_text( string original, int cursor_pos ) { 45 | var str = ""; 46 | var first = true; 47 | MatchInfo match; 48 | foreach( string line in original.split( "\n" ) ) { 49 | if( first ) { 50 | first = false; 51 | } else { 52 | str += "\n"; 53 | } 54 | if( _re.match( line, 0, out match ) ) { 55 | str += match.fetch( 1 ) + "[ ] " + match.fetch( 2 ); 56 | } else { 57 | str += line; 58 | } 59 | } 60 | return( str ); 61 | } 62 | 63 | } 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/functions/markdown/MarkdownTaskRemoveCompleted.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class MarkdownTaskRemoveCompleted : TextFunction { 25 | 26 | Regex _completed_re; 27 | Regex _incompleted_re; 28 | MarkdownTaskApplyType _apply = MarkdownTaskApplyType.LINE; 29 | 30 | /* Constructor */ 31 | public MarkdownTaskRemoveCompleted( bool custom = false ) { 32 | base( "markdown-task-remove-completed", custom ); 33 | try { 34 | _completed_re = new Regex( """^(\s*)\[[xX]\] (.*)$""" ); 35 | _incompleted_re = new Regex( """^(\s*)\[[ ]\] (.*)$""" ); 36 | } catch( RegexError e ) {} 37 | } 38 | 39 | protected override string get_label0() { 40 | return( _( "Remove Completed Markdown Tasks" ) ); 41 | } 42 | 43 | public override TextFunction copy( bool custom ) { 44 | var tf = new MarkdownTaskRemoveCompleted( custom ); 45 | tf._apply = _apply; 46 | return( tf ); 47 | } 48 | 49 | public override bool matches( TextFunction function ) { 50 | return( base.matches( function ) && (_apply == ((MarkdownTaskRemoveCompleted)function)._apply) ); 51 | } 52 | 53 | public override bool settings_available() { 54 | return( true ); 55 | } 56 | 57 | /* Populates the given popover with the settings */ 58 | public override void add_settings( Grid grid ) { 59 | add_menubutton_setting( grid, 0, _( "Apply To" ), _apply, MarkdownTaskApplyType.LENGTH, (value) => { 60 | var apply = (MarkdownTaskApplyType)value; 61 | return( apply.label() ); 62 | }, (value) => { 63 | _apply = (MarkdownTaskApplyType)value; 64 | }); 65 | } 66 | 67 | public override Xml.Node* save() { 68 | Xml.Node* node = base.save(); 69 | node->set_prop( "apply", _apply.to_string() ); 70 | return( node ); 71 | } 72 | 73 | public override void load( Xml.Node* node, TextFunctions functions ) { 74 | base.load( node, functions ); 75 | var a = node->get_prop( "apply" ); 76 | if( a != null ) { 77 | _apply = MarkdownTaskApplyType.parse( a ); 78 | } 79 | } 80 | 81 | private string add_line( string line, ref bool first ) { 82 | if( first ) { 83 | first = false; 84 | return( line ); 85 | } 86 | return( "\n" + line ); 87 | } 88 | 89 | public override string transform_text( string original, int cursor_pos ) { 90 | var str = ""; 91 | var first = true; 92 | var last_deleted = false; 93 | MatchInfo match; 94 | foreach( string line in original.split( "\n" ) ) { 95 | if( _incompleted_re.match( line, 0, out match ) ) { 96 | str += add_line( line, ref first ); 97 | last_deleted = false; 98 | } else if( _completed_re.match( line, 0, out match ) || 99 | ((line.strip() == "") && last_deleted) || 100 | ((_apply == MarkdownTaskApplyType.PARAGRAPH) && last_deleted) ) { 101 | last_deleted = true; 102 | } else { 103 | str += add_line( line, ref first ); 104 | last_deleted = false; 105 | } 106 | } 107 | return( str ); 108 | } 109 | 110 | } 111 | 112 | 113 | -------------------------------------------------------------------------------- /src/functions/markdown/meson.build: -------------------------------------------------------------------------------- 1 | sources += files( 2 | 3 | 'ConvertMarkdownHTML.vala', 4 | 'MarkdownReferences.vala', 5 | 'MarkdownTableBeauty.vala', 6 | 'MarkdownTaskAdd.vala', 7 | 'MarkdownTaskDelete.vala', 8 | 'MarkdownTaskComplete.vala', 9 | 'MarkdownTaskIncomplete.vala', 10 | 'MarkdownTaskRemoveCompleted.vala' 11 | 12 | ) 13 | -------------------------------------------------------------------------------- /src/functions/match/ClearSelected.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class ClearSelected : TextFunction { 25 | 26 | /* Constructor */ 27 | public ClearSelected( bool custom = false ) { 28 | base( "clear-selected", custom ); 29 | } 30 | 31 | protected override string get_label0() { 32 | return( _( "Clear Match Highlight" ) ); 33 | } 34 | 35 | public override TextFunction copy( bool custom ) { 36 | return( new ClearSelected( custom ) ); 37 | } 38 | 39 | /* Returns true if there is matched text within the editor */ 40 | public override bool launchable( Editor editor ) { 41 | return( editor.is_selected() ); 42 | } 43 | 44 | /* Called when the action button is clicked. Displays the UI. */ 45 | public override void launch( Editor editor ) { 46 | var undo_item = new UndoItem( name ); 47 | editor.remove_selected( undo_item ); 48 | editor.undo_buffer.add_item( undo_item ); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/functions/match/InvertSelected.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class InvertSelected : TextFunction { 25 | 26 | /* Constructor */ 27 | public InvertSelected( bool custom = false ) { 28 | base( "invert-selected", custom ); 29 | } 30 | 31 | protected override string get_label0() { 32 | return( _( "Invert Matched Text" ) ); 33 | } 34 | 35 | public override TextFunction copy( bool custom ) { 36 | return( new InvertSelected( custom ) ); 37 | } 38 | 39 | /* Returns true if there is matched text within the editor */ 40 | public override bool launchable( Editor editor ) { 41 | return( editor.is_selected() ); 42 | } 43 | 44 | /* Called when the action button is clicked. Displays the UI. */ 45 | public override void launch( Editor editor ) { 46 | 47 | var undo_item = new UndoItem( name ); 48 | var ranges = new Array(); 49 | editor.get_ranges( ranges ); 50 | 51 | TextIter first, last; 52 | editor.buffer.get_bounds( out first, out last ); 53 | editor.remove_selected( undo_item ); 54 | 55 | for( int i=0; i 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class ReplaceSelected : TextFunction { 25 | 26 | private MainWindow _win; 27 | private string _replace_text = ""; 28 | private Entry _replace; 29 | 30 | private const GLib.ActionEntry action_entries[] = { 31 | { "action_insert_replace", action_insert_replace, "s" }, 32 | }; 33 | 34 | /* Constructor */ 35 | public ReplaceSelected( MainWindow win, bool custom = false ) { 36 | 37 | base( "replace-selected", custom ); 38 | 39 | _win = win; 40 | 41 | } 42 | 43 | protected override string get_label0() { 44 | return( _( "Replace Matched Text" ) ); 45 | } 46 | 47 | public override TextFunction copy( bool custom ) { 48 | return( new ReplaceSelected( _win, custom ) ); 49 | } 50 | 51 | public override bool matches( TextFunction function ) { 52 | return( base.matches( function ) && (_replace_text == ((ReplaceSelected)function)._replace_text) ); 53 | } 54 | 55 | /* Returns true if matched text exists in the editor */ 56 | public override bool launchable( Editor editor ) { 57 | return( editor.is_selected() ); 58 | } 59 | 60 | /* Inserts the given string at the current insertion point */ 61 | private void action_insert_replace( SimpleAction action, Variant? variant ) { 62 | var str = variant.get_string(); 63 | if( str != null ) { 64 | var pos = _replace.cursor_position; 65 | _replace.do_insert_text( str, str.length, ref pos ); 66 | } 67 | } 68 | 69 | /* Creates the search UI */ 70 | private void create_widget( Editor editor, out Box box, out Entry entry ) { 71 | 72 | _replace = new Entry() { 73 | halign = Align.FILL, 74 | hexpand = true, 75 | placeholder_text = _( "Replace With" ), 76 | tooltip_text = _( "Replacement Text" ), 77 | extra_menu = new GLib.Menu() 78 | }; 79 | Utils.populate_insert_popup( (GLib.Menu)_replace.extra_menu, "replace_sel.action_insert_replace" ); 80 | 81 | if( custom ) { 82 | 83 | _replace.text = _replace_text; 84 | _replace.changed.connect(() => { 85 | _replace_text = _replace.text; 86 | custom_changed(); 87 | }); 88 | 89 | } else { 90 | 91 | _replace.activate.connect(() => { 92 | _replace_text = _replace.text; 93 | var undo_item = new UndoItem( label ); 94 | do_replace( editor, undo_item ); 95 | editor.undo_buffer.add_item( undo_item ); 96 | }); 97 | 98 | handle_widget_escape( _replace, _win ); 99 | 100 | entry = _replace; 101 | 102 | } 103 | 104 | box = new Box( Orientation.HORIZONTAL, 5 ); 105 | box.append( _replace ); 106 | 107 | /* Add the menu actions */ 108 | var actions = new SimpleActionGroup(); 109 | actions.add_action_entries( action_entries, this ); 110 | box.insert_action_group( "replace_sel", actions ); 111 | 112 | } 113 | 114 | public override Box? get_widget( Editor editor ) { 115 | Box box; 116 | Entry entry; 117 | create_widget( editor, out box, out entry ); 118 | return( box ); 119 | } 120 | 121 | /* Replace all matches with the replacement text */ 122 | private void do_replace( Editor editor, UndoItem? undo_item ) { 123 | 124 | var ranges = new Array(); 125 | var replace_text = Utils.replace_date( _replace_text ); 126 | var int_value = 1; 127 | 128 | editor.get_ranges( ranges ); 129 | 130 | for( int i=((int)ranges.length - 1); i>=0; i-- ) { 131 | var range = ranges.index( i ); 132 | editor.replace_text( range.start, range.end, Utils.replace_index( replace_text, ref int_value ), undo_item ); 133 | } 134 | 135 | /* Hide the widget */ 136 | _win.remove_widget(); 137 | 138 | } 139 | 140 | public override void run( Editor editor, UndoItem undo_item ) { 141 | do_replace( editor, undo_item ); 142 | } 143 | 144 | /* Called when the action button is clicked. Displays the UI. */ 145 | public override void launch( Editor editor ) { 146 | if( custom ) { 147 | do_replace( editor, null ); 148 | } else { 149 | Box box; 150 | Entry entry; 151 | create_widget( editor, out box, out entry ); 152 | _win.add_widget( box, entry ); 153 | } 154 | } 155 | 156 | public override Xml.Node* save() { 157 | Xml.Node* node = base.save(); 158 | node->set_prop( "replace", _replace_text ); 159 | return( node ); 160 | } 161 | 162 | public override void load( Xml.Node* node, TextFunctions functions ) { 163 | base.load( node, functions ); 164 | string? r = node->get_prop( "replace" ); 165 | if( r != null ) { 166 | _replace_text = r; 167 | } 168 | } 169 | 170 | } 171 | -------------------------------------------------------------------------------- /src/functions/match/meson.build: -------------------------------------------------------------------------------- 1 | sources += files( 2 | 3 | 'ClearSelected.vala', 4 | 'Find.vala', 5 | 'InvertSelected.vala', 6 | 'RegExpr.vala', 7 | 'ReplaceSelected.vala' 8 | 9 | ) 10 | -------------------------------------------------------------------------------- /src/functions/meson.build: -------------------------------------------------------------------------------- 1 | subdir('case') 2 | subdir('convert') 3 | subdir('indent') 4 | subdir('insert') 5 | subdir('markdown') 6 | subdir('match') 7 | subdir('quotes') 8 | subdir('remove') 9 | subdir('repair') 10 | subdir('replace') 11 | subdir('sort') 12 | -------------------------------------------------------------------------------- /src/functions/quotes/QuotesAngled.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class QuotesAngled : TextFunction { 23 | 24 | /* Constructor */ 25 | public QuotesAngled( bool custom = false ) { 26 | base( "quotes-angled", custom, FunctionDirection.NONE ); 27 | } 28 | 29 | protected override string get_label0() { 30 | return( _( "Change to Angled Quotes" ) ); 31 | } 32 | 33 | public override TextFunction copy( bool custom ) { 34 | var fn = new QuotesAngled( custom ); 35 | return( fn ); 36 | } 37 | 38 | /* Perform the transformation */ 39 | public override string transform_text( string original, int cursor_pos ) { 40 | return( substitute_straight_quotes( original, true, false ) ); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/functions/quotes/QuotesCJK.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class QuotesCJK : TextFunction { 23 | 24 | /* Constructor */ 25 | public QuotesCJK( bool custom = false ) { 26 | base( "quotes-cjk", custom, FunctionDirection.NONE ); 27 | } 28 | 29 | protected override string get_label0() { 30 | return( _( "Change to CJK Quotes" ) ); 31 | } 32 | 33 | public override TextFunction copy( bool custom ) { 34 | var fn = new QuotesCJK( custom ); 35 | return( fn ); 36 | } 37 | 38 | /* Perform the transformation */ 39 | public override string transform_text( string original, int cursor_pos ) { 40 | 41 | var str = substitute_straight_quotes( original, false ); 42 | 43 | str = str.replace( right_angled_dquote, right_cjk_dquote ); 44 | str = str.replace( left_angled_dquote, left_cjk_dquote ); 45 | 46 | return( str ); 47 | 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/functions/quotes/QuotesCurved.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class QuotesCurved : TextFunction { 23 | 24 | /* Constructor */ 25 | public QuotesCurved( bool custom = false ) { 26 | base( "quotes-curved", custom, FunctionDirection.NONE ); 27 | } 28 | 29 | protected override string get_label0() { 30 | return( _( "Change to Curved Quotes" ) ); 31 | } 32 | 33 | public override TextFunction copy( bool custom ) { 34 | var fn = new QuotesCurved( custom ); 35 | return( fn ); 36 | } 37 | 38 | /* Perform the transformation */ 39 | public override string transform_text( string original, int cursor_pos ) { 40 | 41 | var str = substitute_straight_quotes( original, true, true ); 42 | 43 | str = str.replace( right_angled_dquote, right_curved_dquote ); 44 | str = str.replace( left_angled_dquote, left_curved_dquote ); 45 | 46 | str = str.replace( right_angled_squote, right_curved_squote ); 47 | str = str.replace( left_angled_squote, left_curved_squote ); 48 | 49 | return( str ); 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/functions/quotes/QuotesDoubleSingle.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class QuotesDoubleSingle : TextFunction { 23 | 24 | /* Constructor */ 25 | public QuotesDoubleSingle( bool custom = false ) { 26 | base( "quotes-double-single", custom, FunctionDirection.LEFT_TO_RIGHT ); 27 | } 28 | 29 | protected override string get_label0() { 30 | return( _( "Double to Single Quotes" ) ); 31 | } 32 | 33 | protected override string get_label1() { 34 | return( _( "Single to Double Quotes" ) ); 35 | } 36 | public override TextFunction copy( bool custom ) { 37 | var fn = new QuotesDoubleSingle( custom ); 38 | fn.direction = direction; 39 | return( fn ); 40 | } 41 | 42 | private string replace_single_with_double( string original, string single, string double ) { 43 | var sbytes = single.length; 44 | var str = original; 45 | var index = str.index_of_char( single.get_char( 0 ) ); 46 | while( index != -1 ) { 47 | if( !is_apostrophe( str, index ) ) { 48 | var prefix = str.slice( 0, index ); 49 | var suffix = str.slice( (index + sbytes), str.length ); 50 | str = prefix + double + suffix; 51 | } 52 | index = str.index_of_char( single.get_char( 0 ), (index + 1) ); 53 | } 54 | return( str ); 55 | } 56 | 57 | /* Perform the transformation */ 58 | public override string transform_text( string original, int cursor_pos ) { 59 | 60 | var str = original; 61 | 62 | if( direction == FunctionDirection.LEFT_TO_RIGHT ) { 63 | 64 | str = str.replace( right_curved_dquote, right_curved_squote ); 65 | str = str.replace( right_angled_dquote, right_angled_squote ); 66 | str = str.replace( right_german_dquote, right_german_squote ); 67 | str = str.replace( left_curved_dquote, left_curved_squote ); 68 | str = str.replace( left_angled_dquote, left_angled_squote ); 69 | str = str.replace( left_german_dquote, left_german_squote ); 70 | str = str.replace( "\"", "'" ); 71 | 72 | } else { 73 | 74 | str = replace_single_with_double( str, right_curved_squote, right_curved_dquote ); 75 | str = str.replace( right_angled_squote, right_angled_dquote ); 76 | str = str.replace( right_german_squote, right_german_dquote ); 77 | str = str.replace( left_curved_squote, left_curved_dquote ); 78 | str = str.replace( left_angled_squote, left_angled_dquote ); 79 | str = str.replace( left_german_squote, left_german_dquote ); 80 | str = replace_single_with_double( str, "'", "\"" ); 81 | 82 | } 83 | 84 | return( str ); 85 | 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/functions/quotes/QuotesGerman.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class QuotesGerman : TextFunction { 23 | 24 | /* Constructor */ 25 | public QuotesGerman( bool custom = false ) { 26 | base( "quotes-german", custom, FunctionDirection.NONE ); 27 | } 28 | 29 | protected override string get_label0() { 30 | return( _( "Change to German Quotes" ) ); 31 | } 32 | 33 | public override TextFunction copy( bool custom ) { 34 | var fn = new QuotesGerman( custom ); 35 | return( fn ); 36 | } 37 | 38 | /* Perform the transformation */ 39 | public override string transform_text( string original, int cursor_pos ) { 40 | 41 | var str = substitute_straight_quotes( original, true, false ); 42 | 43 | str = str.replace( right_angled_dquote, right_german_dquote ); 44 | str = str.replace( left_angled_dquote, left_german_dquote ); 45 | 46 | str = str.replace( right_angled_squote, right_german_squote ); 47 | str = str.replace( left_angled_squote, left_german_squote ); 48 | 49 | return( str ); 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/functions/quotes/QuotesStraight.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class QuotesStraight : TextFunction { 23 | 24 | /* Constructor */ 25 | public QuotesStraight( bool custom = false ) { 26 | base( "quotes-straight", custom, FunctionDirection.NONE ); 27 | } 28 | 29 | protected override string get_label0() { 30 | return( _( "Change to Straight Quotes" ) ); 31 | } 32 | 33 | public override TextFunction copy( bool custom ) { 34 | var fn = new QuotesStraight( custom ); 35 | return( fn ); 36 | } 37 | 38 | /* Perform the transformation */ 39 | public override string transform_text( string original, int cursor_pos ) { 40 | return( straight_quote( original ) ); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/functions/quotes/meson.build: -------------------------------------------------------------------------------- 1 | sources += files( 2 | 3 | 'QuotesAngled.vala', 4 | 'QuotesCJK.vala', 5 | 'QuotesCurved.vala', 6 | 'QuotesDoubleSingle.vala', 7 | 'QuotesGerman.vala', 8 | 'QuotesStraight.vala' 9 | 10 | ) 11 | -------------------------------------------------------------------------------- /src/functions/remove/RemoveBlankLines.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class RemoveBlankLines : TextFunction { 23 | 24 | public RemoveBlankLines( bool custom = false ) { 25 | base( "remove-blank-lines", custom ); 26 | } 27 | 28 | protected override string get_label0() { 29 | return( _( "Remove Blank Lines" ) ); 30 | } 31 | 32 | public override TextFunction copy( bool custom ) { 33 | return( new RemoveBlankLines( custom ) ); 34 | } 35 | 36 | /* Perform the transformation */ 37 | public override string transform_text( string original, int cursor_pos ) { 38 | string[] lines = {}; 39 | foreach( string line in original.split( "\n" ) ) { 40 | if( line.strip() != "" ) { 41 | lines += line; 42 | } 43 | } 44 | return( string.joinv( "\n", lines ) ); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/functions/remove/RemoveDuplicateLines.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gee; 23 | 24 | public class RemoveDuplicateLines : TextFunction { 25 | 26 | public RemoveDuplicateLines( bool custom = false ) { 27 | base( "remove-duplicate-lines", custom ); 28 | } 29 | 30 | protected override string get_label0() { 31 | return( _( "Remove Duplicate Lines" ) ); 32 | } 33 | 34 | public override TextFunction copy( bool custom ) { 35 | return( new RemoveDuplicateLines( custom ) ); 36 | } 37 | 38 | /* Perform the transformation */ 39 | public override string transform_text( string original, int cursor_pos ) { 40 | string[] lines = {}; 41 | var unique_lines = new HashMap(); 42 | foreach( string line in original.split( "\n" ) ) { 43 | if( (line.strip() == "") || !unique_lines.has_key( line ) ) { 44 | unique_lines.set( line, true ); 45 | lines += line; 46 | } 47 | } 48 | return( string.joinv( "\n", lines ) ); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/functions/remove/RemoveLeadingWhitespace.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gee; 23 | 24 | public class RemoveLeadingWhitespace : TextFunction { 25 | 26 | public RemoveLeadingWhitespace( bool custom = false ) { 27 | base( "remove-leading-whitespace", custom ); 28 | } 29 | 30 | protected override string get_label0() { 31 | return( _( "Remove Leading Whitespace" ) ); 32 | } 33 | 34 | public override TextFunction copy( bool custom ) { 35 | return( new RemoveLeadingWhitespace( custom ) ); 36 | } 37 | 38 | /* Perform the transformation */ 39 | public override string transform_text( string original, int cursor_pos ) { 40 | string[] lines = {}; 41 | foreach( string line in original.split( "\n" ) ) { 42 | lines += line.chug(); 43 | } 44 | return( string.joinv( "\n", lines ) ); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/functions/remove/RemoveLineBreaks.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class RemoveLineBreaks : TextFunction { 23 | 24 | public RemoveLineBreaks( bool custom = false ) { 25 | base( "remove-line-breaks", custom ); 26 | } 27 | 28 | protected override string get_label0() { 29 | return( _( "Remove Line Breaks" ) ); 30 | } 31 | 32 | public override TextFunction copy( bool custom ) { 33 | return( new RemoveLineBreaks( custom ) ); 34 | } 35 | 36 | /* Perform the transformation */ 37 | public override string transform_text( string original, int cursor_pos ) { 38 | return( string.joinv( " ", original.split( "\n" ) ) ); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/functions/remove/RemoveLineNumbers.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class RemoveLineNumbers : TextFunction { 23 | 24 | private Regex _re; 25 | 26 | public RemoveLineNumbers( bool custom = false ) { 27 | base( "remove-line-numbers", custom ); 28 | try { 29 | _re = new Regex( """^\s*\d+[^a-zA-Z_\s]?(.*)$""" ); 30 | } catch( RegexError e ) {} 31 | } 32 | 33 | protected override string get_label0() { 34 | return( _( "Remove Line Numbers" ) ); 35 | } 36 | 37 | public override TextFunction copy( bool custom ) { 38 | return( new RemoveLineNumbers( custom ) ); 39 | } 40 | 41 | /* Perform the transformation */ 42 | public override string transform_text( string original, int cursor_pos ) { 43 | string[] lines = {}; 44 | foreach( string line in original.split( "\n" ) ) { 45 | MatchInfo match; 46 | if( _re.match( line, 0, out match ) ) { 47 | lines += match.fetch( 1 ); 48 | } else { 49 | lines += line; 50 | } 51 | } 52 | return( string.joinv( "\n", lines ) ); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/functions/remove/RemoveSelected.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class RemoveSelected : TextFunction { 23 | 24 | public RemoveSelected( bool custom = false ) { 25 | base( "remove-selected", custom ); 26 | } 27 | 28 | protected override string get_label0() { 29 | return( _( "Remove Matched Text" ) ); 30 | } 31 | 32 | public override TextFunction copy( bool custom ) { 33 | return( new RemoveSelected( custom ) ); 34 | } 35 | 36 | /* Returns true if matched text exists in the editor */ 37 | public override bool launchable( Editor editor ) { 38 | return( editor.is_selected() ); 39 | } 40 | 41 | /* Perform the transformation */ 42 | public override string transform_text( string original, int cursor_pos ) { 43 | return( "" ); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/functions/remove/RemoveTrailingWhitespace.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gee; 23 | 24 | public class RemoveTrailingWhitespace : TextFunction { 25 | 26 | public RemoveTrailingWhitespace( bool custom = false ) { 27 | base( "remove-trailing-whitespace", custom ); 28 | } 29 | 30 | protected override string get_label0() { 31 | return( _( "Remove Trailing Whitespace" ) ); 32 | } 33 | 34 | public override TextFunction copy( bool custom ) { 35 | return( new RemoveTrailingWhitespace( custom ) ); 36 | } 37 | 38 | /* Perform the transformation */ 39 | public override string transform_text( string original, int cursor_pos ) { 40 | string[] lines = {}; 41 | foreach( string line in original.split( "\n" ) ) { 42 | lines += line.chomp(); 43 | } 44 | return( string.joinv( "\n", lines ) ); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/functions/remove/meson.build: -------------------------------------------------------------------------------- 1 | sources += files( 2 | 3 | 'RemoveBlankLines.vala', 4 | 'RemoveDuplicateLines.vala', 5 | 'RemoveLeadingWhitespace.vala', 6 | 'RemoveLineBreaks.vala', 7 | 'RemoveLineNumbers.vala', 8 | 'RemoveSelected.vala', 9 | 'RemoveTrailingWhitespace.vala' 10 | 11 | ) 12 | -------------------------------------------------------------------------------- /src/functions/repair/FixSpaces.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class FixSpaces : TextFunction { 25 | 26 | private Regex _extra_re; 27 | private Regex _missing_pre_re; 28 | private Regex _missing_post_re; 29 | private Regex _remove1_re; 30 | private Regex _remove2_re; 31 | 32 | /* Constructor */ 33 | public FixSpaces( bool custom = false ) { 34 | base( "fix-spaces", custom ); 35 | try { 36 | _extra_re = new Regex( """ {2,}""" ); 37 | _missing_pre_re = new Regex( """[^ ]([\(\{\[])""" ); 38 | _missing_post_re = new Regex( """[],.?!\)\}:;%&*-]([^ ])""" ); 39 | _remove1_re = new Regex( """\](\s)\[""" ); 40 | _remove2_re = new Regex( """\](\s)\(""" ); 41 | } catch( RegexError e ) {} 42 | } 43 | 44 | protected override string get_label0() { 45 | return( _( "Fix Spaces" ) ); 46 | } 47 | 48 | public override TextFunction copy( bool custom ) { 49 | return( new FixSpaces( custom ) ); 50 | } 51 | 52 | private string add_space( string text, Regex re ) { 53 | MatchInfo match; 54 | var str = text; 55 | while( re.match( str, 0, out match ) ) { 56 | int start, end; 57 | match.fetch_pos( 1, out start, out end ); 58 | str = str.splice( start, start, " " ); 59 | } 60 | return( str ); 61 | } 62 | 63 | private string remove_space( string text, Regex re ) { 64 | MatchInfo match; 65 | var str = text; 66 | while( re.match( str, 0, out match ) ) { 67 | int start, end; 68 | match.fetch_pos( 1, out start, out end ); 69 | str = str.splice( start, end, "" ); 70 | } 71 | return( str ); 72 | } 73 | 74 | public override string transform_text( string original, int cursor_pos ) { 75 | 76 | MatchInfo match; 77 | int start, end; 78 | var str = ""; 79 | 80 | foreach( string line in original.split( "\n" ) ) { 81 | 82 | /* Remove extra spaces */ 83 | while( _extra_re.match( line, 0, out match ) ) { 84 | match.fetch_pos( 0, out start, out end ); 85 | line = line.splice( start, end, " " ); 86 | } 87 | 88 | /* Add spaces if they are missing */ 89 | line = add_space( line, _missing_pre_re ); 90 | line = add_space( line, _missing_post_re ); 91 | line = remove_space( line, _remove1_re ); 92 | line = remove_space( line, _remove2_re ); 93 | 94 | str += line + "\n"; 95 | 96 | } 97 | 98 | return( str ); 99 | 100 | } 101 | 102 | } 103 | 104 | -------------------------------------------------------------------------------- /src/functions/repair/meson.build: -------------------------------------------------------------------------------- 1 | sources += files( 2 | 3 | 'FixSpaces.vala' 4 | 5 | ) 6 | -------------------------------------------------------------------------------- /src/functions/replace/ReplacePeriodsEllipsis.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class ReplacePeriodsEllipsis : TextFunction { 23 | 24 | /* Constructor */ 25 | public ReplacePeriodsEllipsis( bool custom = false ) { 26 | base( "replace-periods-ellipsis", custom, FunctionDirection.LEFT_TO_RIGHT ); 27 | } 28 | 29 | protected override string get_label0() { 30 | return( _( "Three Periods With Ellipsis" ) ); 31 | } 32 | 33 | protected override string get_label1() { 34 | return( _( "Ellipsis With Three Periods" ) ); 35 | } 36 | 37 | public override TextFunction copy( bool custom ) { 38 | var fn = new ReplacePeriodsEllipsis( custom ); 39 | fn.direction = direction; 40 | return( fn ); 41 | } 42 | 43 | /* Perform the transformation */ 44 | public override string transform_text( string original, int cursor_pos ) { 45 | if( direction == FunctionDirection.LEFT_TO_RIGHT ) { 46 | return( original.replace( "...", "\u2026" ) ); 47 | } else { 48 | return( original.replace( "\u2026", "..." ) ); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/functions/replace/ReplaceReturnSpace.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class ReplaceReturnSpace : TextFunction { 25 | 26 | /* Constructor */ 27 | public ReplaceReturnSpace( bool custom = false ) { 28 | base( "replace-return-space", custom, FunctionDirection.LEFT_TO_RIGHT ); 29 | } 30 | 31 | protected override string get_label0() { 32 | return( _( "Return With Space" ) ); 33 | } 34 | 35 | protected override string get_label1() { 36 | return( _( "Space With Return" ) ); 37 | } 38 | 39 | public override TextFunction copy( bool custom ) { 40 | var fn = new ReplaceReturnSpace( custom ); 41 | fn.direction = direction; 42 | return( fn ); 43 | } 44 | 45 | /* Perform the transformation */ 46 | public override string transform_text( string original, int cursor_pos ) { 47 | if( direction == FunctionDirection.LEFT_TO_RIGHT ) { 48 | return( original.replace( "\n", " " ) ); 49 | } else { 50 | return( original.replace( " ", "\n" ) ); 51 | } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/functions/replace/ReplaceReturns.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class ReplaceReturns : TextFunction { 25 | 26 | private int _returns = 2; 27 | 28 | /* Constructor */ 29 | public ReplaceReturns( bool custom = false ) { 30 | base( "replace-returns", custom, FunctionDirection.LEFT_TO_RIGHT ); 31 | } 32 | 33 | protected override string get_label0() { 34 | return( _( "Single Return With %d Returns" ).printf( _returns ) ); 35 | } 36 | 37 | protected override string get_label1() { 38 | return( _( "%d Returns With Single Return" ).printf( _returns ) ); 39 | } 40 | 41 | public override TextFunction copy( bool custom ) { 42 | var fn = new ReplaceReturns( custom ); 43 | fn.direction = direction; 44 | fn._returns = _returns; 45 | return( fn ); 46 | } 47 | 48 | public override bool matches( TextFunction function ) { 49 | return( base.matches( function ) && (_returns == ((ReplaceReturns)function)._returns) ); 50 | } 51 | 52 | /* Perform the transformation */ 53 | public override string transform_text( string original, int cursor_pos ) { 54 | var returns = string.nfill( _returns, '\n' ); 55 | if( direction == FunctionDirection.LEFT_TO_RIGHT ) { 56 | return( original.replace( "\n", returns ) ); 57 | } else { 58 | return( original.replace( returns, "\n" ) ); 59 | } 60 | } 61 | 62 | /* Specify that we have settings to display */ 63 | public override bool settings_available() { 64 | return( true ); 65 | } 66 | 67 | /* Populates the given popover with the settings */ 68 | public override void add_settings( Grid grid ) { 69 | 70 | add_range_setting( grid, 0, _( "Returns" ), 2, 20, 1, _returns, (value) => { 71 | _returns = value; 72 | update_button_label(); 73 | }); 74 | 75 | } 76 | 77 | public override Xml.Node* save() { 78 | Xml.Node* node = base.save(); 79 | node->set_prop( "returns", _returns.to_string() ); 80 | return( node ); 81 | } 82 | 83 | public override void load( Xml.Node* node, TextFunctions functions ) { 84 | base.load( node, functions ); 85 | var s = node->get_prop( "returns" ); 86 | if( s != null ) { 87 | _returns = int.parse( s ); 88 | } 89 | update_button_label(); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/functions/replace/ReplaceTabsSpaces.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class ReplaceTabsSpaces : TextFunction { 25 | 26 | private int _spaces = 1; 27 | 28 | /* Constructor */ 29 | public ReplaceTabsSpaces( bool custom = false ) { 30 | base( "replace-tabs-spaces", custom, FunctionDirection.LEFT_TO_RIGHT ); 31 | } 32 | 33 | protected override string get_label0() { 34 | if( _spaces == 1 ) { 35 | return( _( "Tabs With 1 Space" ) ); 36 | } else { 37 | return( _( "Tabs With %d Spaces" ).printf( _spaces ) ); 38 | } 39 | } 40 | 41 | protected override string get_label1() { 42 | if( _spaces == 1 ) { 43 | return( _( "1 Space With Tabs" ) ); 44 | } else { 45 | return( _( "%d Spaces With Tabs" ).printf( _spaces ) ); 46 | } 47 | } 48 | 49 | public override TextFunction copy( bool custom ) { 50 | var fn = new ReplaceTabsSpaces( custom ); 51 | fn.direction = direction; 52 | fn._spaces = _spaces; 53 | return( fn ); 54 | } 55 | 56 | public override bool matches( TextFunction function ) { 57 | return( base.matches( function ) && (_spaces == ((ReplaceTabsSpaces)function)._spaces) ); 58 | } 59 | 60 | /* Perform the transformation */ 61 | public override string transform_text( string original, int cursor_pos ) { 62 | var spaces = string.nfill( _spaces, ' ' ); 63 | if( direction == FunctionDirection.LEFT_TO_RIGHT ) { 64 | return( original.replace( "\t", spaces ) ); 65 | } else { 66 | return( original.replace( spaces, "\t" ) ); 67 | } 68 | } 69 | 70 | /* Specify that we have settings to display */ 71 | public override bool settings_available() { 72 | return( true ); 73 | } 74 | 75 | /* Populates the given popover with the settings */ 76 | public override void add_settings( Grid grid ) { 77 | 78 | add_range_setting( grid, 0, _( "Spaces" ), 1, 20, 1, _spaces, (value) => { 79 | _spaces = value; 80 | update_button_label(); 81 | }); 82 | 83 | } 84 | 85 | public override Xml.Node* save() { 86 | Xml.Node* node = base.save(); 87 | node->set_prop( "spaces", _spaces.to_string() ); 88 | return( node ); 89 | } 90 | 91 | public override void load( Xml.Node* node, TextFunctions functions ) { 92 | base.load( node, functions ); 93 | var s = node->get_prop( "spaces" ); 94 | if( s != null ) { 95 | _spaces = int.parse( s ); 96 | } 97 | update_button_label(); 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/functions/replace/meson.build: -------------------------------------------------------------------------------- 1 | sources += files( 2 | 3 | 'ReplacePeriodsEllipsis.vala', 4 | 'ReplaceReturns.vala', 5 | 'ReplaceReturnSpace.vala', 6 | 'ReplaceTabsSpaces.vala' 7 | 8 | ) 9 | -------------------------------------------------------------------------------- /src/functions/sort/SortLines.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class SortLines : TextFunction { 23 | 24 | /* Constructor */ 25 | public SortLines( bool custom = false ) { 26 | base( "sort-lines", custom, FunctionDirection.TOP_DOWN ); 27 | } 28 | 29 | protected override string get_label0() { 30 | return( _( "Sort Lines" ) ); 31 | } 32 | 33 | protected override string get_label1() { 34 | return( _( "Sort Lines Reversed" ) ); 35 | } 36 | 37 | public override TextFunction copy( bool custom ) { 38 | var fn = new SortLines( custom ); 39 | fn.direction = direction; 40 | return( fn ); 41 | } 42 | 43 | /* Perform the transformation */ 44 | public override string transform_text( string original, int cursor_pos ) { 45 | var list = new List(); 46 | var lines = ""; 47 | foreach( string str in original.split( "\n" ) ) { 48 | list.append( str ); 49 | } 50 | list.sort( strcmp ); 51 | if( direction == FunctionDirection.BOTTOM_UP ) { 52 | list.reverse(); 53 | } 54 | list.foreach( (item) => { 55 | lines += item + "\n"; 56 | }); 57 | return( lines.chomp() ); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/functions/sort/SortMoveLines.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | using Gtk; 23 | 24 | public class SortMoveLines : TextFunction { 25 | 26 | private int _count; 27 | 28 | /* Constructor */ 29 | public SortMoveLines( bool custom = false ) { 30 | base( "sort-move-lines", custom, FunctionDirection.TOP_DOWN ); 31 | _count = 1; 32 | } 33 | 34 | protected override string get_label0() { 35 | if( _count == 1 ) { 36 | return( _( "Move 1 Line Down" ) ); 37 | } else { 38 | return( _( "Move %d Lines Down" ).printf( _count ) ); 39 | } 40 | } 41 | 42 | protected override string get_label1() { 43 | if( _count == 1 ) { 44 | return( _( "Move 1 Line Up" ) ); 45 | } else { 46 | return( _( "Move %d Lines Up" ).printf( _count ) ); 47 | } 48 | } 49 | 50 | public override TextFunction copy( bool custom ) { 51 | var fn = new SortMoveLines( custom ); 52 | fn._count = _count; 53 | return( fn ); 54 | } 55 | 56 | public override bool matches( TextFunction function ) { 57 | return( base.matches( function ) && (_count == ((SortMoveLines)function)._count) ); 58 | } 59 | 60 | public override void launch( Editor editor ) { 61 | 62 | TextIter start, end, first, last, cursor; 63 | string text = ""; 64 | 65 | var buf = editor.buffer; 66 | var selected = buf.has_selection; 67 | var down = (direction == FunctionDirection.TOP_DOWN); 68 | 69 | buf.get_iter_at_mark( out cursor, buf.get_insert() ); 70 | var cursor_line = cursor.get_line(); 71 | var cursor_col = cursor.get_line_offset(); 72 | 73 | /* Get the lines that need to be moved */ 74 | if( !buf.get_selection_bounds( out start, out end ) ) { 75 | buf.get_iter_at_mark( out start, buf.get_insert() ); 76 | end = start; 77 | } 78 | 79 | var start_line = start.get_line(); 80 | var start_col = start.get_line_offset(); 81 | var end_line = end.get_line(); 82 | var end_col = end.get_line_offset(); 83 | 84 | /* Adjust the start and end iterators so that they encompass the entire line */ 85 | buf.get_iter_at_line( out start, start.get_line() ); 86 | if( !end.ends_line() ) end.forward_to_line_end(); 87 | 88 | text = start.get_slice( end ); 89 | first = start; 90 | last = end; 91 | 92 | if( down ) { 93 | if( !last.forward_lines( _count ) ) return; 94 | last.forward_to_line_end(); 95 | end.forward_char(); 96 | text = end.get_slice( last ) + "\n" + text; 97 | } else { 98 | if( !first.backward_lines( _count ) ) return; 99 | start.backward_char(); 100 | text = text + "\n" + first.get_slice( start ); 101 | } 102 | 103 | /* Adjust the text */ 104 | var undo_item = new UndoItem( label ); 105 | editor.replace_text( first, last, text, undo_item ); 106 | editor.undo_buffer.add_item( undo_item ); 107 | 108 | var adjust = down ? _count : (0 - _count); 109 | 110 | /* Adjust the selection, if necessary */ 111 | if( selected ) { 112 | buf.get_iter_at_line_offset( out start, (start_line + adjust), start_col ); 113 | buf.get_iter_at_line_offset( out end, (end_line + adjust), end_col ); 114 | buf.select_range( start, end ); 115 | } 116 | 117 | /* Adjust the cursor */ 118 | buf.get_iter_at_line_offset( out start, (cursor_line + adjust), cursor_col ); 119 | buf.place_cursor( start ); 120 | 121 | } 122 | 123 | public override bool settings_available() { 124 | return( true ); 125 | } 126 | 127 | public override void add_settings( Grid grid ) { 128 | 129 | add_range_setting( grid, 0, _( "Lines" ), 1, 1000, 1, _count, (value) => { 130 | _count = value; 131 | update_button_label(); 132 | }); 133 | 134 | } 135 | 136 | public override Xml.Node* save() { 137 | Xml.Node* node = base.save(); 138 | node->set_prop( "count", _count.to_string() ); 139 | return( node ); 140 | } 141 | 142 | public override void load( Xml.Node* node, TextFunctions functions ) { 143 | base.load( node, functions ); 144 | var c = node->get_prop( "count" ); 145 | if( c != null ) { 146 | _count = int.parse( c ); 147 | } 148 | } 149 | 150 | } 151 | -------------------------------------------------------------------------------- /src/functions/sort/SortReverseChars.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 (https://github.com/phase1geo/TextShine) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Trevor Williams 20 | */ 21 | 22 | public class SortReverseChars : TextFunction { 23 | 24 | /* Constructor */ 25 | public SortReverseChars( bool custom = false ) { 26 | base( "sort-reverse", custom ); 27 | } 28 | 29 | protected override string get_label0() { 30 | return( _( "Reverse Characters" ) ); 31 | } 32 | 33 | public override TextFunction copy( bool custom ) { 34 | return( new SortReverseChars( custom ) ); 35 | } 36 | 37 | /* Perform the transformation */ 38 | public override string transform_text( string original, int cursor_pos ) { 39 | return( original.reverse() ); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/functions/sort/meson.build: -------------------------------------------------------------------------------- 1 | sources += files( 2 | 3 | 'Randomize.vala', 4 | 'SortLines.vala', 5 | 'SortMoveLines.vala', 6 | 'SortReverseChars.vala' 7 | 8 | ) 9 | -------------------------------------------------------------------------------- /src/meson.build: -------------------------------------------------------------------------------- 1 | sources += files( 2 | 3 | 'Application.vala', 4 | 'CustomFunction.vala', 5 | 'Editor.vala', 6 | 'MainWindow.vala', 7 | 'Preferences.vala', 8 | 'Sidebar.vala', 9 | 'SidebarBox.vala', 10 | 'SidebarCustom.vala', 11 | 'SidebarFunctions.vala', 12 | 'SpellChecker.vala', 13 | 'TextFunction.vala', 14 | 'TextFunctions.vala', 15 | 'UndoBuffer.vala', 16 | 'UndoCustomBuffer.vala', 17 | 'UndoCustomItem.vala', 18 | 'UndoItem.vala', 19 | 'Utils.vala' 20 | 21 | ) 22 | 23 | subdir('functions') 24 | -------------------------------------------------------------------------------- /vapi/libmarkdown.vapi: -------------------------------------------------------------------------------- 1 | [CCode (cprefix = "mkd")] 2 | namespace Markdown { 3 | 4 | [Compact] 5 | [CCode (cheader_filename = "mkdio.h", cname = "MMIOT", free_function = "mkd_cleanup")] 6 | public class Document { 7 | 8 | [CCode (cname = "mkd_string")] 9 | public Document.format (uint8[] data, int flag = 0); 10 | 11 | [CCode (cname = "gfm_string")] 12 | public Document.gfm_format (uint8[] data, int flag = 0); 13 | 14 | [CCode (cname = "mkd_compile")] 15 | public void compile (int flag = 0); 16 | 17 | [CCode (cname = "mkd_document")] 18 | public int get_document (out unowned string result); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /vapi/mkdio.h: -------------------------------------------------------------------------------- 1 | #ifndef _MKDIO_D 2 | #define _MKDIO_D 3 | 4 | #include 5 | 6 | typedef void MMIOT; 7 | 8 | typedef unsigned int mkd_flag_t; 9 | 10 | /* line builder for markdown() 11 | */ 12 | MMIOT *mkd_in(FILE*,mkd_flag_t); /* assemble input from a file */ 13 | MMIOT *mkd_string(const char*,int,mkd_flag_t); /* assemble input from a buffer */ 14 | 15 | /* line builder for github flavoured markdown 16 | */ 17 | MMIOT *gfm_in(FILE*,mkd_flag_t); /* assemble input from a file */ 18 | MMIOT *gfm_string(const char*,int,mkd_flag_t); /* assemble input from a buffer */ 19 | 20 | void mkd_basename(MMIOT*,char*); 21 | 22 | void mkd_initialize(); 23 | void mkd_with_html5_tags(); 24 | void mkd_shlib_destructor(); 25 | 26 | /* compilation, debugging, cleanup 27 | */ 28 | int mkd_compile(MMIOT*, mkd_flag_t); 29 | void mkd_cleanup(MMIOT*); 30 | 31 | /* markup functions 32 | */ 33 | int mkd_dump(MMIOT*, FILE*, int, char*); 34 | int markdown(MMIOT*, FILE*, mkd_flag_t); 35 | int mkd_line(char *, int, char **, mkd_flag_t); 36 | typedef int (*mkd_sta_function_t)(const int,const void*); 37 | void mkd_string_to_anchor(char *, int, mkd_sta_function_t, void*, int); 38 | int mkd_xhtmlpage(MMIOT*,int,FILE*); 39 | 40 | /* header block access 41 | */ 42 | char* mkd_doc_title(MMIOT*); 43 | char* mkd_doc_author(MMIOT*); 44 | char* mkd_doc_date(MMIOT*); 45 | 46 | /* compiled data access 47 | */ 48 | int mkd_document(MMIOT*, char**); 49 | int mkd_toc(MMIOT*, char**); 50 | int mkd_css(MMIOT*, char **); 51 | int mkd_xml(char *, int, char **); 52 | 53 | /* write-to-file functions 54 | */ 55 | int mkd_generatehtml(MMIOT*,FILE*); 56 | int mkd_generatetoc(MMIOT*,FILE*); 57 | int mkd_generatexml(char *, int,FILE*); 58 | int mkd_generatecss(MMIOT*,FILE*); 59 | #define mkd_style mkd_generatecss 60 | int mkd_generateline(char *, int, FILE*, mkd_flag_t); 61 | #define mkd_text mkd_generateline 62 | 63 | /* url generator callbacks 64 | */ 65 | typedef char * (*mkd_callback_t)(const char*, const int, void*); 66 | typedef void (*mkd_free_t)(char*, void*); 67 | 68 | void mkd_e_url(void *, mkd_callback_t); 69 | void mkd_e_flags(void *, mkd_callback_t); 70 | void mkd_e_free(void *, mkd_free_t ); 71 | void mkd_e_data(void *, void *); 72 | 73 | /* version#. 74 | */ 75 | extern char markdown_version[]; 76 | void mkd_mmiot_flags(FILE *, MMIOT *, int); 77 | void mkd_flags_are(FILE*, mkd_flag_t, int); 78 | 79 | void mkd_ref_prefix(MMIOT*, char*); 80 | 81 | 82 | /* special flags for markdown() and mkd_text() 83 | */ 84 | #define MKD_NOLINKS 0x00000001 /* don't do link processing, block tags */ 85 | #define MKD_NOIMAGE 0x00000002 /* don't do image processing, block */ 86 | #define MKD_NOPANTS 0x00000004 /* don't run smartypants() */ 87 | #define MKD_NOHTML 0x00000008 /* don't allow raw html through AT ALL */ 88 | #define MKD_STRICT 0x00000010 /* disable SUPERSCRIPT, RELAXED_EMPHASIS */ 89 | #define MKD_TAGTEXT 0x00000020 /* process text inside an html tag; no 90 | * , no , no html or [] expansion */ 91 | #define MKD_NO_EXT 0x00000040 /* don't allow pseudo-protocols */ 92 | #define MKD_NOEXT MKD_NO_EXT /* ^^^ (aliased for user convenience) */ 93 | #define MKD_CDATA 0x00000080 /* generate code for xml ![CDATA[...]] */ 94 | #define MKD_NOSUPERSCRIPT 0x00000100 /* no A^B */ 95 | #define MKD_NORELAXED 0x00000200 /* emphasis happens /everywhere/ */ 96 | #define MKD_NOTABLES 0x00000400 /* disallow tables */ 97 | #define MKD_NOSTRIKETHROUGH 0x00000800 /* forbid ~~strikethrough~~ */ 98 | #define MKD_TOC 0x00001000 /* do table-of-contents processing */ 99 | #define MKD_1_COMPAT 0x00002000 /* compatibility with MarkdownTest_1.0 */ 100 | #define MKD_AUTOLINK 0x00004000 /* make http://foo.com link even without <>s */ 101 | #define MKD_SAFELINK 0x00008000 /* paranoid check for link protocol */ 102 | #define MKD_NOHEADER 0x00010000 /* don't process header blocks */ 103 | #define MKD_TABSTOP 0x00020000 /* expand tabs to 4 spaces */ 104 | #define MKD_NODIVQUOTE 0x00040000 /* forbid >%class% blocks */ 105 | #define MKD_NOALPHALIST 0x00080000 /* forbid alphabetic lists */ 106 | #define MKD_NODLIST 0x00100000 /* forbid definition lists */ 107 | #define MKD_EXTRA_FOOTNOTE 0x00200000 /* enable markdown extra-style footnotes */ 108 | #define MKD_NOSTYLE 0x00400000 /* don't extract