| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828 |
- (function webpackUniversalModuleDefinition(root, factory) {
- if(typeof exports === 'object' && typeof module === 'object')
- module.exports = factory();
- else if(typeof define === 'function' && define.amd)
- define("TableEditor", [], factory);
- else if(typeof exports === 'object')
- exports["TableEditor"] = factory();
- else
- root["TableEditor"] = factory();
- })(typeof self !== 'undefined' ? self : this, function() {
- return /******/ (function(modules) { // webpackBootstrap
- /******/ // The module cache
- /******/ var installedModules = {};
- /******/
- /******/ // The require function
- /******/ function __webpack_require__(moduleId) {
- /******/
- /******/ // Check if module is in cache
- /******/ if(installedModules[moduleId]) {
- /******/ return installedModules[moduleId].exports;
- /******/ }
- /******/ // Create a new module (and put it into the cache)
- /******/ var module = installedModules[moduleId] = {
- /******/ i: moduleId,
- /******/ l: false,
- /******/ exports: {}
- /******/ };
- /******/
- /******/ // Execute the module function
- /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
- /******/
- /******/ // Flag the module as loaded
- /******/ module.l = true;
- /******/
- /******/ // Return the exports of the module
- /******/ return module.exports;
- /******/ }
- /******/
- /******/
- /******/ // expose the modules object (__webpack_modules__)
- /******/ __webpack_require__.m = modules;
- /******/
- /******/ // expose the module cache
- /******/ __webpack_require__.c = installedModules;
- /******/
- /******/ // define getter function for harmony exports
- /******/ __webpack_require__.d = function(exports, name, getter) {
- /******/ if(!__webpack_require__.o(exports, name)) {
- /******/ Object.defineProperty(exports, name, {
- /******/ configurable: false,
- /******/ enumerable: true,
- /******/ get: getter
- /******/ });
- /******/ }
- /******/ };
- /******/
- /******/ // getDefaultExport function for compatibility with non-harmony modules
- /******/ __webpack_require__.n = function(module) {
- /******/ var getter = module && module.__esModule ?
- /******/ function getDefault() { return module['default']; } :
- /******/ function getModuleExports() { return module; };
- /******/ __webpack_require__.d(getter, 'a', getter);
- /******/ return getter;
- /******/ };
- /******/
- /******/ // Object.prototype.hasOwnProperty.call
- /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
- /******/
- /******/ // __webpack_public_path__
- /******/ __webpack_require__.p = "";
- /******/
- /******/ // Load entry module and return exports
- /******/ return __webpack_require__(__webpack_require__.s = 0);
- /******/ })
- /************************************************************************/
- /******/ ([
- /* 0 */
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
- /* harmony export (immutable) */ __webpack_exports__["initTableEditor"] = initTableEditor;
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__susisu_mte_kernel__ = __webpack_require__(1);
- /* global CodeMirror, $ */
- // port of the code from: https://github.com/susisu/mte-demo/blob/master/src/main.js
- // text editor interface
- // see https://doc.esdoc.org/github.com/susisu/mte-kernel/class/lib/text-editor.js~ITextEditor.html
- class TextEditorInterface {
- constructor (editor) {
- this.editor = editor
- this.doc = editor.getDoc()
- this.transaction = false
- this.onDidFinishTransaction = null
- }
- getCursorPosition () {
- const { line, ch } = this.doc.getCursor()
- return new __WEBPACK_IMPORTED_MODULE_0__susisu_mte_kernel__["c" /* Point */](line, ch)
- }
- setCursorPosition (pos) {
- this.doc.setCursor({ line: pos.row, ch: pos.column })
- }
- setSelectionRange (range) {
- this.doc.setSelection(
- { line: range.start.row, ch: range.start.column },
- { line: range.end.row, ch: range.end.column }
- )
- }
- getLastRow () {
- return this.doc.lineCount() - 1
- }
- acceptsTableEdit () {
- return true
- }
- getLine (row) {
- return this.doc.getLine(row)
- }
- insertLine (row, line) {
- const lastRow = this.getLastRow()
- if (row > lastRow) {
- const lastLine = this.getLine(lastRow)
- this.doc.replaceRange(
- '\n' + line,
- { line: lastRow, ch: lastLine.length },
- { line: lastRow, ch: lastLine.length }
- )
- } else {
- this.doc.replaceRange(
- line + '\n',
- { line: row, ch: 0 },
- { line: row, ch: 0 }
- )
- }
- }
- deleteLine (row) {
- const lastRow = this.getLastRow()
- if (row >= lastRow) {
- if (lastRow > 0) {
- const preLastLine = this.getLine(lastRow - 1)
- const lastLine = this.getLine(lastRow)
- this.doc.replaceRange(
- '',
- { line: lastRow - 1, ch: preLastLine.length },
- { line: lastRow, ch: lastLine.length }
- )
- } else {
- const lastLine = this.getLine(lastRow)
- this.doc.replaceRange(
- '',
- { line: lastRow, ch: 0 },
- { line: lastRow, ch: lastLine.length }
- )
- }
- } else {
- this.doc.replaceRange(
- '',
- { line: row, ch: 0 },
- { line: row + 1, ch: 0 }
- )
- }
- }
- replaceLines (startRow, endRow, lines) {
- const lastRow = this.getLastRow()
- if (endRow > lastRow) {
- const lastLine = this.getLine(lastRow)
- this.doc.replaceRange(
- lines.join('\n'),
- { line: startRow, ch: 0 },
- { line: lastRow, ch: lastLine.length }
- )
- } else {
- this.doc.replaceRange(
- lines.join('\n') + '\n',
- { line: startRow, ch: 0 },
- { line: endRow, ch: 0 }
- )
- }
- }
- transact (func) {
- this.transaction = true
- func()
- this.transaction = false
- if (this.onDidFinishTransaction) {
- this.onDidFinishTransaction.call(undefined)
- }
- }
- }
- function initTableEditor (editor) {
- // create an interface to the text editor
- const editorIntf = new TextEditorInterface(editor)
- // create a table editor object
- const tableEditor = new __WEBPACK_IMPORTED_MODULE_0__susisu_mte_kernel__["d" /* TableEditor */](editorIntf)
- // options for the table editor
- const opts = Object(__WEBPACK_IMPORTED_MODULE_0__susisu_mte_kernel__["e" /* options */])({
- smartCursor: true,
- formatType: __WEBPACK_IMPORTED_MODULE_0__susisu_mte_kernel__["b" /* FormatType */].NORMAL
- })
- // keymap of the commands
- // from https://github.com/susisu/mte-demo/blob/master/src/main.js
- const keyMap = CodeMirror.normalizeKeyMap({
- Tab: () => { tableEditor.nextCell(opts) },
- 'Shift-Tab': () => { tableEditor.previousCell(opts) },
- Enter: () => { tableEditor.nextRow(opts) },
- 'Ctrl-Enter': () => { tableEditor.escape(opts) },
- 'Cmd-Enter': () => { tableEditor.escape(opts) },
- 'Shift-Ctrl-Left': () => { tableEditor.alignColumn(__WEBPACK_IMPORTED_MODULE_0__susisu_mte_kernel__["a" /* Alignment */].LEFT, opts) },
- 'Shift-Cmd-Left': () => { tableEditor.alignColumn(__WEBPACK_IMPORTED_MODULE_0__susisu_mte_kernel__["a" /* Alignment */].LEFT, opts) },
- 'Shift-Ctrl-Right': () => { tableEditor.alignColumn(__WEBPACK_IMPORTED_MODULE_0__susisu_mte_kernel__["a" /* Alignment */].RIGHT, opts) },
- 'Shift-Cmd-Right': () => { tableEditor.alignColumn(__WEBPACK_IMPORTED_MODULE_0__susisu_mte_kernel__["a" /* Alignment */].RIGHT, opts) },
- 'Shift-Ctrl-Up': () => { tableEditor.alignColumn(__WEBPACK_IMPORTED_MODULE_0__susisu_mte_kernel__["a" /* Alignment */].CENTER, opts) },
- 'Shift-Cmd-Up': () => { tableEditor.alignColumn(__WEBPACK_IMPORTED_MODULE_0__susisu_mte_kernel__["a" /* Alignment */].CENTER, opts) },
- 'Shift-Ctrl-Down': () => { tableEditor.alignColumn(__WEBPACK_IMPORTED_MODULE_0__susisu_mte_kernel__["a" /* Alignment */].NONE, opts) },
- 'Shift-Cmd-Down': () => { tableEditor.alignColumn(__WEBPACK_IMPORTED_MODULE_0__susisu_mte_kernel__["a" /* Alignment */].NONE, opts) },
- 'Ctrl-Left': () => { tableEditor.moveFocus(0, -1, opts) },
- 'Cmd-Left': () => { tableEditor.moveFocus(0, -1, opts) },
- 'Ctrl-Right': () => { tableEditor.moveFocus(0, 1, opts) },
- 'Cmd-Right': () => { tableEditor.moveFocus(0, 1, opts) },
- 'Ctrl-Up': () => { tableEditor.moveFocus(-1, 0, opts) },
- 'Cmd-Up': () => { tableEditor.moveFocus(-1, 0, opts) },
- 'Ctrl-Down': () => { tableEditor.moveFocus(1, 0, opts) },
- 'Cmd-Down': () => { tableEditor.moveFocus(1, 0, opts) },
- 'Ctrl-K Ctrl-I': () => { tableEditor.insertRow(opts) },
- 'Cmd-K Cmd-I': () => { tableEditor.insertRow(opts) },
- 'Ctrl-L Ctrl-I': () => { tableEditor.deleteRow(opts) },
- 'Cmd-L Cmd-I': () => { tableEditor.deleteRow(opts) },
- 'Ctrl-K Ctrl-J': () => { tableEditor.insertColumn(opts) },
- 'Cmd-K Cmd-J': () => { tableEditor.insertColumn(opts) },
- 'Ctrl-L Ctrl-J': () => { tableEditor.deleteColumn(opts) },
- 'Cmd-L Cmd-J': () => { tableEditor.deleteColumn(opts) },
- 'Alt-Shift-Ctrl-Left': () => { tableEditor.moveColumn(-1, opts) },
- 'Alt-Shift-Cmd-Left': () => { tableEditor.moveColumn(-1, opts) },
- 'Alt-Shift-Ctrl-Right': () => { tableEditor.moveColumn(1, opts) },
- 'Alt-Shift-Cmd-Right': () => { tableEditor.moveColumn(1, opts) },
- 'Alt-Shift-Ctrl-Up': () => { tableEditor.moveRow(-1, opts) },
- 'Alt-Shift-Cmd-Up': () => { tableEditor.moveRow(-1, opts) },
- 'Alt-Shift-Ctrl-Down': () => { tableEditor.moveRow(1, opts) },
- 'Alt-Shift-Cmd-Down': () => { tableEditor.moveRow(1, opts) }
- })
- // enable keymap if the cursor is in a table
- function updateActiveState() {
- const active = tableEditor.cursorIsInTable();
- if (active) {
- editor.setOption("extraKeys", keyMap);
- }
- else {
- editor.setOption("extraKeys", null);
- tableEditor.resetSmartCursor();
- }
- }
- // event subscriptions
- editor.on("cursorActivity", () => {
- if (!editorIntf.transaction) {
- updateActiveState();
- }
- });
- editor.on("changes", () => {
- if (!editorIntf.transaction) {
- updateActiveState();
- }
- });
- editorIntf.onDidFinishTransaction = () => {
- updateActiveState();
- };
- return tableEditor
- }
- /***/ }),
- /* 1 */
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return Point; });
- /* unused harmony export Range */
- /* unused harmony export Focus */
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Alignment; });
- /* unused harmony export DefaultAlignment */
- /* unused harmony export HeaderAlignment */
- /* unused harmony export TableCell */
- /* unused harmony export TableRow */
- /* unused harmony export Table */
- /* unused harmony export readTable */
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return FormatType; });
- /* unused harmony export completeTable */
- /* unused harmony export formatTable */
- /* unused harmony export alterAlignment */
- /* unused harmony export insertRow */
- /* unused harmony export deleteRow */
- /* unused harmony export moveRow */
- /* unused harmony export insertColumn */
- /* unused harmony export deleteColumn */
- /* unused harmony export moveColumn */
- /* unused harmony export Insert */
- /* unused harmony export Delete */
- /* unused harmony export applyEditScript */
- /* unused harmony export shortestEditScript */
- /* unused harmony export ITextEditor */
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "e", function() { return options; });
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return TableEditor; });
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_meaw__ = __webpack_require__(2);
- /**
- * A `Point` represents a point in the text editor.
- */
- class Point {
- /**
- * Creates a new `Point` object.
- *
- * @param {number} row - Row of the point, starts from 0.
- * @param {number} column - Column of the point, starts from 0.
- */
- constructor(row, column) {
- /** @private */
- this._row = row;
- /** @private */
- this._column = column;
- }
- /**
- * Row of the point.
- *
- * @type {number}
- */
- get row() {
- return this._row;
- }
- /**
- * Column of the point.
- *
- * @type {number}
- */
- get column() {
- return this._column;
- }
- /**
- * Checks if the point is equal to another point.
- *
- * @param {Point} point - A point object.
- * @returns {boolean} `true` if two points are equal.
- */
- equals(point) {
- return this.row === point.row && this.column === point.column;
- }
- }
- /**
- * A `Range` object represents a range in the text editor.
- */
- class Range {
- /**
- * Creates a new `Range` object.
- *
- * @param {Point} start - The start point of the range.
- * @param {Point} end - The end point of the range.
- */
- constructor(start, end) {
- /** @private */
- this._start = start;
- /** @private */
- this._end = end;
- }
- /**
- * The start point of the range.
- *
- * @type {Point}
- */
- get start() {
- return this._start;
- }
- /**
- * The end point of the range.
- *
- * @type {Point}
- */
- get end() {
- return this._end;
- }
- }
- /**
- * A `Focus` object represents which cell is focused in the table.
- *
- * Note that `row` and `column` properties specifiy a cell's position in the table, not the cursor's
- * position in the text editor as {@link Point} class.
- *
- * @private
- */
- class Focus {
- /**
- * Creates a new `Focus` object.
- *
- * @param {number} row - Row of the focused cell.
- * @param {number} column - Column of the focused cell.
- * @param {number} offset - Raw offset in the cell.
- */
- constructor(row, column, offset) {
- /** @private */
- this._row = row;
- /** @private */
- this._column = column;
- /** @private */
- this._offset = offset;
- }
- /**
- * Row of the focused cell.
- *
- * @type {number}
- */
- get row() {
- return this._row;
- }
- /**
- * Column of the focused cell.
- *
- * @type {number}
- */
- get column() {
- return this._column;
- }
- /**
- * Raw offset in the cell.
- *
- * @type {number}
- */
- get offset() {
- return this._offset;
- }
- /**
- * Checks if two focuses point the same cell.
- * Offsets are ignored.
- *
- * @param {Focus} focus - A focus object.
- * @returns {boolean}
- */
- posEquals(focus) {
- return this.row === focus.row && this.column === focus.column;
- }
- /**
- * Creates a copy of the focus object by setting its row to the specified value.
- *
- * @param {number} row - Row of the focused cell.
- * @returns {Focus} A new focus object with the specified row.
- */
- setRow(row) {
- return new Focus(row, this.column, this.offset);
- }
- /**
- * Creates a copy of the focus object by setting its column to the specified value.
- *
- * @param {number} column - Column of the focused cell.
- * @returns {Focus} A new focus object with the specified column.
- */
- setColumn(column) {
- return new Focus(this.row, column, this.offset);
- }
- /**
- * Creates a copy of the focus object by setting its offset to the specified value.
- *
- * @param {number} offset - Offset in the focused cell.
- * @returns {Focus} A new focus object with the specified offset.
- */
- setOffset(offset) {
- return new Focus(this.row, this.column, offset);
- }
- }
- /**
- * Represents column alignment.
- *
- * - `Alignment.NONE` - Use default alignment.
- * - `Alignment.LEFT` - Align left.
- * - `Alignment.RIGHT` - Align right.
- * - `Alignment.CENTER` - Align center.
- *
- * @type {Object}
- */
- const Alignment = Object.freeze({
- NONE : "none",
- LEFT : "left",
- RIGHT : "right",
- CENTER: "center"
- });
- /**
- * Represents default column alignment
- *
- * - `DefaultAlignment.LEFT` - Align left.
- * - `DefaultAlignment.RIGHT` - Align right.
- * - `DefaultAlignment.CENTER` - Align center.
- *
- * @type {Object}
- */
- const DefaultAlignment = Object.freeze({
- LEFT : Alignment.LEFT,
- RIGHT : Alignment.RIGHT,
- CENTER: Alignment.CENTER
- });
- /**
- * Represents alignment of header cells.
- *
- * - `HeaderAlignment.FOLLOW` - Follow column's alignment.
- * - `HeaderAlignment.LEFT` - Align left.
- * - `HeaderAlignment.RIGHT` - Align right.
- * - `HeaderAlignment.CENTER` - Align center.
- *
- * @type {Object}
- */
- const HeaderAlignment = Object.freeze({
- FOLLOW: "follow",
- LEFT : Alignment.LEFT,
- RIGHT : Alignment.RIGHT,
- CENTER: Alignment.CENTER
- });
- /**
- * A `TableCell` object represents a table cell.
- *
- * @private
- */
- class TableCell {
- /**
- * Creates a new `TableCell` object.
- *
- * @param {string} rawContent - Raw content of the cell.
- */
- constructor(rawContent) {
- /** @private */
- this._rawContent = rawContent;
- /** @private */
- this._content = rawContent.trim();
- /** @private */
- this._paddingLeft = this._content === ""
- ? (this._rawContent === "" ? 0 : 1)
- : this._rawContent.length - this._rawContent.trimLeft().length;
- /** @private */
- this._paddingRight = this._rawContent.length - this._content.length - this._paddingLeft;
- }
- /**
- * Raw content of the cell.
- *
- * @type {string}
- */
- get rawContent() {
- return this._rawContent;
- }
- /**
- * Trimmed content of the cell.
- *
- * @type {string}
- */
- get content() {
- return this._content;
- }
- /**
- * Width of the left padding of the cell.
- *
- * @type {number}
- */
- get paddingLeft() {
- return this._paddingLeft;
- }
- /**
- * Width of the right padding of the cell.
- *
- * @type {number}
- */
- get paddingRight() {
- return this._paddingRight;
- }
- /**
- * Convers the cell to a text representation.
- *
- * @returns {string} The raw content of the cell.
- */
- toText() {
- return this.rawContent;
- }
- /**
- * Checks if the cell is a delimiter i.e. it only contains hyphens `-` with optional one
- * leading and trailing colons `:`.
- *
- * @returns {boolean} `true` if the cell is a delimiter.
- */
- isDelimiter() {
- return /^\s*:?-+:?\s*$/.test(this.rawContent);
- }
- /**
- * Returns the alignment the cell represents.
- *
- * @returns {Alignment|undefined} The alignment the cell represents;
- * `undefined` if the cell is not a delimiter.
- */
- getAlignment() {
- if (!this.isDelimiter()) {
- return undefined;
- }
- if (this.content[0] === ":") {
- if (this.content[this.content.length - 1] === ":") {
- return Alignment.CENTER;
- }
- else {
- return Alignment.LEFT;
- }
- }
- else {
- if (this.content[this.content.length - 1] === ":") {
- return Alignment.RIGHT;
- }
- else {
- return Alignment.NONE;
- }
- }
- }
- /**
- * Computes a relative position in the trimmed content from that in the raw content.
- *
- * @param {number} rawOffset - Relative position in the raw content.
- * @returns {number} - Relative position in the trimmed content.
- */
- computeContentOffset(rawOffset) {
- if (this.content === "") {
- return 0;
- }
- if (rawOffset < this.paddingLeft) {
- return 0;
- }
- if (rawOffset < this.paddingLeft + this.content.length) {
- return rawOffset - this.paddingLeft;
- }
- else {
- return this.content.length;
- }
- }
- /**
- * Computes a relative position in the raw content from that in the trimmed content.
- *
- * @param {number} contentOffset - Relative position in the trimmed content.
- * @returns {number} - Relative position in the raw content.
- */
- computeRawOffset(contentOffset) {
- return contentOffset + this.paddingLeft;
- }
- }
- /**
- * A `TableRow` object represents a table row.
- *
- * @private
- */
- class TableRow {
- /**
- * Creates a new `TableRow` objec.
- *
- * @param {Array<TableCell>} cells - Cells that the row contains.
- * @param {string} marginLeft - Margin string at the left of the row.
- * @param {string} marginRight - Margin string at the right of the row.
- */
- constructor(cells, marginLeft, marginRight) {
- /** @private */
- this._cells = cells.slice();
- /** @private */
- this._marginLeft = marginLeft;
- /** @private */
- this._marginRight = marginRight;
- }
- /**
- * Margin string at the left of the row.
- *
- * @type {string}
- */
- get marginLeft() {
- return this._marginLeft;
- }
- /**
- * Margin string at the right of the row.
- *
- * @type {string}
- */
- get marginRight() {
- return this._marginRight;
- }
- /**
- * Gets the number of the cells in the row.
- *
- * @returns {number} Number of the cells.
- */
- getWidth() {
- return this._cells.length;
- }
- /**
- * Returns the cells that the row contains.
- *
- * @returns {Array<TableCell>} An array of cells that the row contains.
- */
- getCells() {
- return this._cells.slice();
- }
- /**
- * Gets a cell at the specified index.
- *
- * @param {number} index - Index.
- * @returns {TableCell|undefined} The cell at the specified index if exists;
- * `undefined` if no cell is found.
- */
- getCellAt(index) {
- return this._cells[index];
- }
- /**
- * Convers the row to a text representation.
- *
- * @returns {string} A text representation of the row.
- */
- toText() {
- if (this._cells.length === 0) {
- return this.marginLeft;
- }
- else {
- const cells = this._cells.map(cell => cell.toText()).join("|");
- return `${this.marginLeft}|${cells}|${this.marginRight}`;
- }
- }
- /**
- * Checks if the row is a delimiter or not.
- *
- * @returns {boolean} `true` if the row is a delimiter i.e. all the cells contained are delimiters.
- */
- isDelimiter() {
- return this._cells.every(cell => cell.isDelimiter());
- }
- }
- /**
- * A `Table` object represents a table.
- *
- * @private
- */
- class Table {
- /**
- * Creates a new `Table` object.
- *
- * @param {Array<TableRow>} rows - An array of rows that the table contains.
- */
- constructor(rows) {
- /** @private */
- this._rows = rows.slice();
- }
- /**
- * Gets the number of rows in the table.
- *
- * @returns {number} The number of rows.
- */
- getHeight() {
- return this._rows.length;
- }
- /**
- * Gets the maximum width of the rows in the table.
- *
- * @returns {number} The maximum width of the rows.
- */
- getWidth() {
- return this._rows.map(row => row.getWidth())
- .reduce((x, y) => Math.max(x, y), 0);
- }
- /**
- * Gets the width of the header row.
- *
- * @returns {number|undefined} The width of the header row;
- * `undefined` if there is no header row.
- */
- getHeaderWidth() {
- if (this._rows.length === 0) {
- return undefined;
- }
- return this._rows[0].getWidth();
- }
- /**
- * Gets the rows that the table contains.
- *
- * @returns {Array<TableRow>} An array of the rows.
- */
- getRows() {
- return this._rows.slice();
- }
- /**
- * Gets a row at the specified index.
- *
- * @param {number} index - Row index.
- * @returns {TableRow|undefined} The row at the specified index;
- * `undefined` if not found.
- */
- getRowAt(index) {
- return this._rows[index];
- }
- /**
- * Gets the delimiter row of the table.
- *
- * @returns {TableRow|undefined} The delimiter row;
- * `undefined` if there is not delimiter row.
- */
- getDelimiterRow() {
- const row = this._rows[1];
- if (row === undefined) {
- return undefined;
- }
- if (row.isDelimiter()) {
- return row;
- }
- else {
- return undefined;
- }
- }
- /**
- * Gets a cell at the specified index.
- *
- * @param {number} rowIndex - Row index of the cell.
- * @param {number} columnIndex - Column index of the cell.
- * @returns {TableCell|undefined} The cell at the specified index;
- * `undefined` if not found.
- */
- getCellAt(rowIndex, columnIndex) {
- const row = this._rows[rowIndex];
- if (row === undefined) {
- return undefined;
- }
- return row.getCellAt(columnIndex);
- }
- /**
- * Gets the cell at the focus.
- *
- * @param {Focus} focus - Focus object.
- * @returns {TableCell|undefined} The cell at the focus;
- * `undefined` if not found.
- */
- getFocusedCell(focus) {
- return this.getCellAt(focus.row, focus.column);
- }
- /**
- * Converts the table to an array of text representations of the rows.
- *
- * @returns {Array<string>} An array of text representations of the rows.
- */
- toLines() {
- return this._rows.map(row => row.toText());
- }
- /**
- * Computes a focus from a point in the text editor.
- *
- * @param {Point} pos - A point in the text editor.
- * @param {number} rowOffset - The row index where the table starts in the text editor.
- * @returns {Focus|undefined} A focus object that corresponds to the specified point;
- * `undefined` if the row index is out of bounds.
- */
- focusOfPosition(pos, rowOffset) {
- const rowIndex = pos.row - rowOffset;
- const row = this._rows[rowIndex];
- if (row === undefined) {
- return undefined;
- }
- if (pos.column < row.marginLeft.length + 1) {
- return new Focus(rowIndex, -1, pos.column);
- }
- else {
- const cellWidths = row.getCells().map(cell => cell.rawContent.length);
- let columnPos = row.marginLeft.length + 1; // left margin + a pipe
- let columnIndex = 0;
- for (; columnIndex < cellWidths.length; columnIndex++) {
- if (columnPos + cellWidths[columnIndex] + 1 > pos.column) {
- break;
- }
- columnPos += cellWidths[columnIndex] + 1;
- }
- const offset = pos.column - columnPos;
- return new Focus(rowIndex, columnIndex, offset);
- }
- }
- /**
- * Computes a position in the text editor from a focus.
- *
- * @param {Focus} focus - A focus object.
- * @param {number} rowOffset - The row index where the table starts in the text editor.
- * @returns {Point|undefined} A position in the text editor that corresponds to the focus;
- * `undefined` if the focused row is out of the table.
- */
- positionOfFocus(focus, rowOffset) {
- const row = this._rows[focus.row];
- if (row === undefined) {
- return undefined;
- }
- const rowPos = focus.row + rowOffset;
- if (focus.column < 0) {
- return new Point(rowPos, focus.offset);
- }
- const cellWidths = row.getCells().map(cell => cell.rawContent.length);
- const maxIndex = Math.min(focus.column, cellWidths.length);
- let columnPos = row.marginLeft.length + 1;
- for (let columnIndex = 0; columnIndex < maxIndex; columnIndex++) {
- columnPos += cellWidths[columnIndex] + 1;
- }
- return new Point(rowPos, columnPos + focus.offset);
- }
- /**
- * Computes a selection range from a focus.
- *
- * @param {Focus} focus - A focus object.
- * @param {number} rowOffset - The row index where the table starts in the text editor.
- * @returns {Range|undefined} A range to be selected that corresponds to the focus;
- * `undefined` if the focus does not specify any cell or the specified cell is empty.
- */
- selectionRangeOfFocus(focus, rowOffset) {
- const row = this._rows[focus.row];
- if (row === undefined) {
- return undefined;
- }
- const cell = row.getCellAt(focus.column);
- if (cell === undefined) {
- return undefined;
- }
- if (cell.content === "") {
- return undefined;
- }
- const rowPos = focus.row + rowOffset;
- const cellWidths = row.getCells().map(cell => cell.rawContent.length);
- let columnPos = row.marginLeft.length + 1;
- for (let columnIndex = 0; columnIndex < focus.column; columnIndex++) {
- columnPos += cellWidths[columnIndex] + 1;
- }
- columnPos += cell.paddingLeft;
- return new Range(
- new Point(rowPos, columnPos),
- new Point(rowPos, columnPos + cell.content.length)
- );
- }
- }
- /**
- * Splits a text into cells.
- *
- * @private
- * @param {string} text
- * @returns {Array<string>}
- */
- function _splitCells(text) {
- const cells = [];
- let buf = "";
- let rest = text;
- while (rest !== "") {
- switch (rest[0]) {
- case "`":
- // read code span
- {
- const start = rest.match(/^`*/)[0];
- let buf1 = start;
- let rest1 = rest.substr(start.length);
- let closed = false;
- while (rest1 !== "") {
- if (rest1[0] === "`") {
- const end = rest1.match(/^`*/)[0];
- buf1 += end;
- rest1 = rest1.substr(end.length);
- if (end.length === start.length) {
- closed = true;
- break;
- }
- }
- else {
- buf1 += rest1[0];
- rest1 = rest1.substr(1);
- }
- }
- if (closed) {
- buf += buf1;
- rest = rest1;
- }
- else {
- buf += "`";
- rest = rest.substr(1);
- }
- }
- break;
- case "\\":
- // escape next character
- if (rest.length >= 2) {
- buf += rest.substr(0, 2);
- rest = rest.substr(2);
- }
- else {
- buf += "\\";
- rest = rest.substr(1);
- }
- break;
- case "|":
- // flush buffer
- cells.push(buf);
- buf = "";
- rest = rest.substr(1);
- break;
- default:
- buf += rest[0];
- rest = rest.substr(1);
- }
- }
- cells.push(buf);
- return cells;
- }
- /**
- * Reads a table row.
- *
- * @private
- * @param {string} text - A text
- * @returns {TableRow}
- */
- function _readRow(text) {
- let cells = _splitCells(text);
- let marginLeft;
- if (cells.length > 0 && /^\s*$/.test(cells[0])) {
- marginLeft = cells[0];
- cells = cells.slice(1);
- }
- else {
- marginLeft = "";
- }
- let marginRight;
- if (cells.length > 1 && /^\s*$/.test(cells[cells.length - 1])) {
- marginRight = cells[cells.length - 1];
- cells = cells.slice(0, cells.length - 1);
- }
- else {
- marginRight = "";
- }
- return new TableRow(cells.map(cell => new TableCell(cell)), marginLeft, marginRight);
- }
- /**
- * Reads a table from lines.
- *
- * @private
- * @param {Array<string>} lines - An array of texts, each text represents a row.
- * @returns {Table} The table red from the lines.
- */
- function readTable(lines) {
- return new Table(lines.map(_readRow));
- }
- /**
- * Creates a delimiter text.
- *
- * @private
- * @param {Alignment} alignment
- * @param {number} width - Width of the horizontal bar of delimiter.
- * @returns {string}
- * @throws {Error} Unknown alignment.
- */
- function _delimiterText(alignment, width) {
- const bar = "-".repeat(width);
- switch (alignment) {
- case Alignment.NONE:
- return ` ${bar} `;
- case Alignment.LEFT:
- return `:${bar} `;
- case Alignment.RIGHT:
- return ` ${bar}:`;
- case Alignment.CENTER:
- return `:${bar}:`;
- default:
- throw new Error("Unknown alignment: " + alignment);
- }
- }
- /**
- * Extends array size.
- *
- * @private
- * @param {Array} arr
- * @param {number} size
- * @param {Function} callback - Callback function to fill newly created cells.
- * @returns {Array} Extended array.
- */
- function _extendArray(arr, size, callback) {
- const extended = arr.slice();
- for (let i = arr.length; i < size; i++) {
- extended.push(callback(i, arr));
- }
- return extended;
- }
- /**
- * Completes a table by adding missing delimiter and cells.
- * After completion, all rows in the table have the same width.
- *
- * @private
- * @param {Table} table - A table object.
- * @param {Object} options - An object containing options for completion.
- *
- * | property name | type | description |
- * | ------------------- | -------------- | --------------------------------------------------------- |
- * | `minDelimiterWidth` | {@link number} | Width of delimiters used when completing delimiter cells. |
- *
- * @returns {Object} An object that represents the result of the completion.
- *
- * | property name | type | description |
- * | ------------------- | --------------- | -------------------------------------- |
- * | `table` | {@link Table} | A completed table object. |
- * | `delimiterInserted` | {@link boolean} | `true` if a delimiter row is inserted. |
- *
- * @throws {Error} Empty table.
- */
- function completeTable(table, options) {
- const tableHeight = table.getHeight();
- const tableWidth = table.getWidth();
- if (tableHeight === 0) {
- throw new Error("Empty table");
- }
- const rows = table.getRows();
- const newRows = [];
- // header
- const headerRow = rows[0];
- const headerCells = headerRow.getCells();
- newRows.push(new TableRow(
- _extendArray(headerCells, tableWidth, j => new TableCell(
- j === headerCells.length ? headerRow.marginRight : ""
- )),
- headerRow.marginLeft,
- headerCells.length < tableWidth ? "" : headerRow.marginRight
- ));
- // delimiter
- const delimiterRow = table.getDelimiterRow();
- if (delimiterRow !== undefined) {
- const delimiterCells = delimiterRow.getCells();
- newRows.push(new TableRow(
- _extendArray(delimiterCells, tableWidth, j => new TableCell(
- _delimiterText(
- Alignment.NONE,
- j === delimiterCells.length
- ? Math.max(options.minDelimiterWidth, delimiterRow.marginRight.length - 2)
- : options.minDelimiterWidth
- )
- )),
- delimiterRow.marginLeft,
- delimiterCells.length < tableWidth ? "" : delimiterRow.marginRight
- ));
- }
- else {
- newRows.push(new TableRow(
- _extendArray([], tableWidth, () => new TableCell(
- _delimiterText(Alignment.NONE, options.minDelimiterWidth)
- )),
- "",
- ""
- ));
- }
- // body
- for (let i = delimiterRow !== undefined ? 2 : 1; i < tableHeight; i++) {
- const row = rows[i];
- const cells = row.getCells();
- newRows.push(new TableRow(
- _extendArray(cells, tableWidth, j => new TableCell(
- j === cells.length ? row.marginRight : ""
- )),
- row.marginLeft,
- cells.length < tableWidth ? "" : row.marginRight
- ));
- }
- return {
- table : new Table(newRows),
- delimiterInserted: delimiterRow === undefined
- };
- }
- /**
- * Calculates the width of a text based on characters' EAW properties.
- *
- * @private
- * @param {string} text
- * @param {Object} options -
- *
- * | property name | type |
- * | ----------------- | ---------------------------------- |
- * | `normalize` | {@link boolean} |
- * | `wideChars` | {@link Set}<{@link string} > |
- * | `narrowChars` | {@link Set}<{@link string} > |
- * | `ambiguousAsWide` | {@link boolean} |
- *
- * @returns {number} Calculated width of the text.
- */
- function _computeTextWidth(text, options) {
- const normalized = options.normalize ? text.normalize("NFC") : text;
- let w = 0;
- for (const char of normalized) {
- if (options.wideChars.has(char)) {
- w += 2;
- continue;
- }
- if (options.narrowChars.has(char)) {
- w += 1;
- continue;
- }
- switch (Object(__WEBPACK_IMPORTED_MODULE_0_meaw__["a" /* getEAW */])(char)) {
- case "F":
- case "W":
- w += 2;
- break;
- case "A":
- w += options.ambiguousAsWide ? 2 : 1;
- break;
- default:
- w += 1;
- }
- }
- return w;
- }
- /**
- * Returns a aligned cell content.
- *
- * @private
- * @param {string} text
- * @param {number} width
- * @param {Alignment} alignment
- * @param {Object} options - Options for computing text width.
- * @returns {string}
- * @throws {Error} Unknown alignment.
- * @throws {Error} Unexpected default alignment.
- */
- function _alignText(text, width, alignment, options) {
- const space = width - _computeTextWidth(text, options);
- if (space < 0) {
- return text;
- }
- switch (alignment) {
- case Alignment.NONE:
- throw new Error("Unexpected default alignment");
- case Alignment.LEFT:
- return text + " ".repeat(space);
- case Alignment.RIGHT:
- return " ".repeat(space) + text;
- case Alignment.CENTER:
- return " ".repeat(Math.floor(space / 2))
- + text
- + " ".repeat(Math.ceil(space / 2));
- default:
- throw new Error("Unknown alignment: " + alignment);
- }
- }
- /**
- * Just adds one space paddings to both sides of a text.
- *
- * @private
- * @param {string} text
- * @returns {string}
- */
- function _padText(text) {
- return ` ${text} `;
- }
- /**
- * Formats a table.
- *
- * @private
- * @param {Table} table - A table object.
- * @param {Object} options - An object containing options for formatting.
- *
- * | property name | type | description |
- * | ------------------- | ------------------------ | ------------------------------------------------------- |
- * | `minDelimiterWidth` | {@link number} | Minimum width of delimiters. |
- * | `defaultAlignment` | {@link DefaultAlignment} | Default alignment of columns. |
- * | `headerAlignment` | {@link HeaderAlignment} | Alignment of header cells. |
- * | `textWidthOptions` | {@link Object} | An object containing options for computing text widths. |
- *
- * `options.textWidthOptions` must contain the following options.
- *
- * | property name | type | description |
- * | ----------------- | --------------------------------- | --------------------------------------------------- |
- * | `normalize` | {@link boolean} | Normalize texts before computing text widths. |
- * | `wideChars` | {@link Set}<{@link string}> | Set of characters that should be treated as wide. |
- * | `narrowChars` | {@link Set}<{@link string}> | Set of characters that should be treated as narrow. |
- * | `ambiguousAsWide` | {@link boolean} | Treat East Asian Ambiguous characters as wide. |
- *
- * @returns {Object} An object that represents the result of formatting.
- *
- * | property name | type | description |
- * | --------------- | -------------- | ---------------------------------------------- |
- * | `table` | {@link Table} | A formatted table object. |
- * | `marginLeft` | {@link string} | The common left margin of the formatted table. |
- */
- function _formatTable(table, options) {
- const tableHeight = table.getHeight();
- const tableWidth = table.getWidth();
- if (tableHeight === 0) {
- return {
- table,
- marginLeft: ""
- };
- }
- const marginLeft = table.getRowAt(0).marginLeft;
- if (tableWidth === 0) {
- const rows = new Array(tableHeight).fill()
- .map(() => new TableRow([], marginLeft, ""));
- return {
- table: new Table(rows),
- marginLeft
- };
- }
- // compute column widths
- const delimiterRow = table.getDelimiterRow();
- const columnWidths = new Array(tableWidth).fill(0);
- if (delimiterRow !== undefined) {
- const delimiterRowWidth = delimiterRow.getWidth();
- for (let j = 0; j < delimiterRowWidth; j++) {
- columnWidths[j] = options.minDelimiterWidth;
- }
- }
- for (let i = 0; i < tableHeight; i++) {
- if (delimiterRow !== undefined && i === 1) {
- continue;
- }
- const row = table.getRowAt(i);
- const rowWidth = row.getWidth();
- for (let j = 0; j < rowWidth; j++) {
- columnWidths[j] = Math.max(
- columnWidths[j],
- _computeTextWidth(row.getCellAt(j).content, options.textWidthOptions)
- );
- }
- }
- // get column alignments
- const alignments = delimiterRow !== undefined
- ? _extendArray(
- delimiterRow.getCells().map(cell => cell.getAlignment()),
- tableWidth,
- () => options.defaultAlignment
- )
- : new Array(tableWidth).fill(options.defaultAlignment);
- // format
- const rows = [];
- // header
- const headerRow = table.getRowAt(0);
- rows.push(new TableRow(
- headerRow.getCells().map((cell, j) =>
- new TableCell(_padText(_alignText(
- cell.content,
- columnWidths[j],
- options.headerAlignment === HeaderAlignment.FOLLOW
- ? (alignments[j] === Alignment.NONE ? options.defaultAlignment : alignments[j])
- : options.headerAlignment,
- options.textWidthOptions
- )))
- ),
- marginLeft,
- ""
- ));
- // delimiter
- if (delimiterRow !== undefined) {
- rows.push(new TableRow(
- delimiterRow.getCells().map((cell, j) =>
- new TableCell(_delimiterText(alignments[j], columnWidths[j]))
- ),
- marginLeft,
- ""
- ));
- }
- // body
- for (let i = delimiterRow !== undefined ? 2 : 1; i < tableHeight; i++) {
- const row = table.getRowAt(i);
- rows.push(new TableRow(
- row.getCells().map((cell, j) =>
- new TableCell(_padText(_alignText(
- cell.content,
- columnWidths[j],
- alignments[j] === Alignment.NONE ? options.defaultAlignment : alignments[j],
- options.textWidthOptions
- )))
- ),
- marginLeft,
- ""
- ));
- }
- return {
- table: new Table(rows),
- marginLeft
- };
- }
- /**
- * Formats a table weakly.
- * Rows are formatted independently to each other, cell contents are just trimmed and not aligned.
- * This is useful when using a non-monospaced font or dealing with wide tables.
- *
- * @private
- * @param {Table} table - A table object.
- * @param {Object} options - An object containing options for formatting.
- * The function accepts the same option object for {@link formatTable}, but properties not listed
- * here are just ignored.
- *
- * | property name | type | description |
- * | ------------------- | -------------- | -------------------- |
- * | `minDelimiterWidth` | {@link number} | Width of delimiters. |
- *
- * @returns {Object} An object that represents the result of formatting.
- *
- * | property name | type | description |
- * | --------------- | -------------- | ---------------------------------------------- |
- * | `table` | {@link Table} | A formatted table object. |
- * | `marginLeft` | {@link string} | The common left margin of the formatted table. |
- */
- function _weakFormatTable(table, options) {
- const tableHeight = table.getHeight();
- const tableWidth = table.getWidth();
- if (tableHeight === 0) {
- return {
- table,
- marginLeft: ""
- };
- }
- const marginLeft = table.getRowAt(0).marginLeft;
- if (tableWidth === 0) {
- const rows = new Array(tableHeight).fill()
- .map(() => new TableRow([], marginLeft, ""));
- return {
- table: new Table(rows),
- marginLeft
- };
- }
- const delimiterRow = table.getDelimiterRow();
- // format
- const rows = [];
- // header
- const headerRow = table.getRowAt(0);
- rows.push(new TableRow(
- headerRow.getCells().map(cell =>
- new TableCell(_padText(cell.content))
- ),
- marginLeft,
- ""
- ));
- // delimiter
- if (delimiterRow !== undefined) {
- rows.push(new TableRow(
- delimiterRow.getCells().map(cell =>
- new TableCell(_delimiterText(cell.getAlignment(), options.minDelimiterWidth))
- ),
- marginLeft,
- ""
- ));
- }
- // body
- for (let i = delimiterRow !== undefined ? 2 : 1; i < tableHeight; i++) {
- const row = table.getRowAt(i);
- rows.push(new TableRow(
- row.getCells().map(cell =>
- new TableCell(_padText(cell.content))
- ),
- marginLeft,
- ""
- ));
- }
- return {
- table: new Table(rows),
- marginLeft
- };
- }
- /**
- * Represents table format type.
- *
- * - `FormatType.NORMAL` - Formats table normally.
- * - `FormatType.WEAK` - Formats table weakly, rows are formatted independently to each other, cell
- * contents are just trimmed and not aligned.
- *
- * @type {Object}
- */
- const FormatType = Object.freeze({
- NORMAL: "normal",
- WEAK : "weak"
- });
- /**
- * Formats a table.
- *
- * @private
- * @param {Table} table - A table object.
- * @param {Object} options - An object containing options for formatting.
- *
- * | property name | type | description |
- * | ------------------- | ------------------------ | ------------------------------------------------------- |
- * | `formatType` | {@link FormatType} | Format type, normal or weak. |
- * | `minDelimiterWidth` | {@link number} | Minimum width of delimiters. |
- * | `defaultAlignment` | {@link DefaultAlignment} | Default alignment of columns. |
- * | `headerAlignment` | {@link HeaderAlignment} | Alignment of header cells. |
- * | `textWidthOptions` | {@link Object} | An object containing options for computing text widths. |
- *
- * `options.textWidthOptions` must contain the following options.
- *
- * | property name | type | description |
- * | ----------------- | --------------------------------- | --------------------------------------------------- |
- * | `normalize` | {@link boolean} | Normalize texts before computing text widths. |
- * | `wideChars` | {@link Set}<{@link string}> | Set of characters that should be treated as wide. |
- * | `narrowChars` | {@link Set}<{@link string}> | Set of characters that should be treated as narrow. |
- * | `ambiguousAsWide` | {@link boolean} | Treat East Asian Ambiguous characters as wide. |
- *
- * @returns {Object} An object that represents the result of formatting.
- *
- * | property name | type | description |
- * | --------------- | -------------- | ---------------------------------------------- |
- * | `table` | {@link Table} | A formatted table object. |
- * | `marginLeft` | {@link string} | The common left margin of the formatted table. |
- *
- * @throws {Error} Unknown format type.
- */
- function formatTable(table, options) {
- switch (options.formatType) {
- case FormatType.NORMAL:
- return _formatTable(table, options);
- case FormatType.WEAK:
- return _weakFormatTable(table, options);
- default:
- throw new Error("Unknown format type: " + options.formatType);
- }
- }
- /**
- * Alters a column's alignment of a table.
- *
- * @private
- * @param {Table} table - A completed non-empty table.
- * @param {number} columnIndex - An index of the column.
- * @param {Alignment} alignment - A new alignment of the column.
- * @param {Object} options - An object containing options for completion.
- *
- * | property name | type | description |
- * | ------------------- | -------------- | -------------------- |
- * | `minDelimiterWidth` | {@link number} | Width of delimiters. |
- *
- * @returns {Table} An altered table object.
- * If the column index is out of range, returns the original table.
- */
- function alterAlignment(table, columnIndex, alignment, options) {
- const delimiterRow = table.getRowAt(1);
- if (columnIndex < 0 || delimiterRow.getWidth() - 1 < columnIndex) {
- return table;
- }
- const delimiterCells = delimiterRow.getCells();
- delimiterCells[columnIndex] = new TableCell(_delimiterText(alignment, options.minDelimiterWidth));
- const rows = table.getRows();
- rows[1] = new TableRow(delimiterCells, delimiterRow.marginLeft, delimiterRow.marginRight);
- return new Table(rows);
- }
- /**
- * Inserts a row to a table.
- * The row is always inserted after the header and the delimiter rows, even if the index specifies
- * the header or the delimiter.
- *
- * @private
- * @param {Table} table - A completed non-empty table.
- * @param {number} rowIndex - An row index at which a new row will be inserted.
- * @param {TableRow} row - A table row to be inserted.
- * @returns {Table} An altered table obejct.
- */
- function insertRow(table, rowIndex, row) {
- const rows = table.getRows();
- rows.splice(Math.max(rowIndex, 2), 0, row);
- return new Table(rows);
- }
- /**
- * Deletes a row in a table.
- * If the index specifies the header row, the cells are emptied but the row will not be removed.
- * If the index specifies the delimiter row, it does nothing.
- *
- * @private
- * @param {Table} table - A completed non-empty table.
- * @param {number} rowIndex - An index of the row to be deleted.
- * @returns {Table} An altered table obejct.
- */
- function deleteRow(table, rowIndex) {
- if (rowIndex === 1) {
- return table;
- }
- const rows = table.getRows();
- if (rowIndex === 0) {
- const headerRow = rows[0];
- rows[0] = new TableRow(
- new Array(headerRow.getWidth()).fill(new TableCell("")),
- headerRow.marginLeft,
- headerRow.marginRight
- );
- }
- else {
- rows.splice(rowIndex, 1);
- }
- return new Table(rows);
- }
- /**
- * Moves a row at the index to the specified destination.
- *
- * @private
- * @param {Table} table - A completed non-empty table.
- * @param {number} rowIndex - Index of the row to be moved.
- * @param {number} destIndex - Index of the destination.
- * @returns {Table} An altered table object.
- */
- function moveRow(table, rowIndex, destIndex) {
- if (rowIndex <= 1 || destIndex <= 1 || rowIndex === destIndex) {
- return table;
- }
- const rows = table.getRows();
- const row = rows[rowIndex];
- rows.splice(rowIndex, 1);
- rows.splice(destIndex, 0, row);
- return new Table(rows);
- }
- /**
- * Inserts a column to a table.
- *
- * @private
- * @param {Table} table - A completed non-empty table.
- * @param {number} columnIndex - An column index at which the new column will be inserted.
- * @param {Array<TableCell>} column - An array of cells.
- * @param {Object} options - An object containing options for completion.
- *
- * | property name | type | description |
- * | ------------------- | -------------- | ----------------------- |
- * | `minDelimiterWidth` | {@link number} | Width of the delimiter. |
- *
- * @returns {Table} An altered table obejct.
- */
- function insertColumn(table, columnIndex, column, options) {
- const rows = table.getRows();
- for (let i = 0; i < rows.length; i++) {
- const row = rows[i];
- const cells = rows[i].getCells();
- const cell = i === 1
- ? new TableCell(_delimiterText(Alignment.NONE, options.minDelimiterWidth))
- : column[i > 1 ? i - 1 : i];
- cells.splice(columnIndex, 0, cell);
- rows[i] = new TableRow(cells, row.marginLeft, row.marginRight);
- }
- return new Table(rows);
- }
- /**
- * Deletes a column in a table.
- * If there will be no columns after the deletion, the cells are emptied but the column will not be
- * removed.
- *
- * @private
- * @param {Table} table - A completed non-empty table.
- * @param {number} columnIndex - An index of the column to be deleted.
- * @param {Object} options - An object containing options for completion.
- *
- * | property name | type | description |
- * | ------------------- | -------------- | ----------------------- |
- * | `minDelimiterWidth` | {@link number} | Width of the delimiter. |
- *
- * @returns {Table} An altered table object.
- */
- function deleteColumn(table, columnIndex, options) {
- const rows = table.getRows();
- for (let i = 0; i < rows.length; i++) {
- const row = rows[i];
- let cells = row.getCells();
- if (cells.length <= 1) {
- cells = [new TableCell(i === 1
- ? _delimiterText(Alignment.NONE, options.minDelimiterWidth)
- : ""
- )];
- }
- else {
- cells.splice(columnIndex, 1);
- }
- rows[i] = new TableRow(cells, row.marginLeft, row.marginRight);
- }
- return new Table(rows);
- }
- /**
- * Moves a column at the index to the specified destination.
- *
- * @private
- * @param {Table} table - A completed non-empty table.
- * @param {number} columnIndex - Index of the column to be moved.
- * @param {number} destIndex - Index of the destination.
- * @returns {Table} An altered table object.
- */
- function moveColumn(table, columnIndex, destIndex) {
- if (columnIndex === destIndex) {
- return table;
- }
- const rows = table.getRows();
- for (let i = 0; i < rows.length; i++) {
- const row = rows[i];
- const cells = row.getCells();
- const cell = cells[columnIndex];
- cells.splice(columnIndex, 1);
- cells.splice(destIndex, 0, cell);
- rows[i] = new TableRow(cells, row.marginLeft, row.marginRight);
- }
- return new Table(rows);
- }
- /**
- * The `Insert` class represents an insertion of a line.
- *
- * @private
- */
- class Insert {
- /**
- * Creats a new `Insert` object.
- *
- * @param {number} row - Row index, starts from `0`.
- * @param {string} line - A string to be inserted at the row.
- */
- constructor(row, line) {
- /** @private */
- this._row = row;
- /** @private */
- this._line = line;
- }
- /**
- * Row index, starts from `0`.
- *
- * @type {number}
- */
- get row() {
- return this._row;
- }
- /**
- * A string to be inserted.
- *
- * @type {string}
- */
- get line() {
- return this._line;
- }
- }
- /**
- * The `Delete` class represents a deletion of a line.
- *
- * @private
- */
- class Delete {
- /**
- * Creates a new `Delete` object.
- *
- * @param {number} row - Row index, starts from `0`.
- */
- constructor(row) {
- /** @private */
- this._row = row;
- }
- /**
- * Row index, starts from `0`.
- *
- * @type {number}
- */
- get row() {
- return this._row;
- }
- }
- /**
- * Applies a command to the text editor.
- *
- * @private
- * @param {ITextEditor} textEditor - An interface to the text editor.
- * @param {Insert|Delete} command - A command.
- * @param {number} rowOffset - Offset to the row index of the command.
- * @returns {undefined}
- */
- function _applyCommand(textEditor, command, rowOffset) {
- if (command instanceof Insert) {
- textEditor.insertLine(rowOffset + command.row, command.line);
- }
- else if (command instanceof Delete) {
- textEditor.deleteLine(rowOffset + command.row);
- }
- else {
- throw new Error("Unknown command");
- }
- }
- /**
- * Apply an edit script (array of commands) to the text editor.
- *
- * @private
- * @param {ITextEditor} textEditor - An interface to the text editor.
- * @param {Array<Insert|Delete>} script - An array of commands.
- * The commands are applied sequentially in the order of the array.
- * @param {number} rowOffset - Offset to the row index of the commands.
- * @returns {undefined}
- */
- function applyEditScript(textEditor, script, rowOffset) {
- for (const command of script) {
- _applyCommand(textEditor, command, rowOffset);
- }
- }
- /**
- * Linked list used to remember edit script.
- *
- * @private
- */
- class IList {
- get car() {
- throw new Error("Not implemented");
- }
- get cdr() {
- throw new Error("Not implemented");
- }
- isEmpty() {
- throw new Error("Not implemented");
- }
- unshift(value) {
- return new Cons(value, this);
- }
- toArray() {
- const arr = [];
- let rest = this;
- while (!rest.isEmpty()) {
- arr.push(rest.car);
- rest = rest.cdr;
- }
- return arr;
- }
- }
- /**
- * @private
- */
- class Nil extends IList {
- constructor() {
- super();
- }
- get car() {
- throw new Error("Empty list");
- }
- get cdr() {
- throw new Error("Empty list");
- }
- isEmpty() {
- return true;
- }
- }
- /**
- * @private
- */
- class Cons extends IList {
- constructor(car, cdr) {
- super();
- this._car = car;
- this._cdr = cdr;
- }
- get car() {
- return this._car;
- }
- get cdr() {
- return this._cdr;
- }
- isEmpty() {
- return false;
- }
- }
- const nil = new Nil();
- /**
- * Computes the shortest edit script between two arrays of strings.
- *
- * @private
- * @param {Array<string>} from - An array of string the edit starts from.
- * @param {Array<string>} to - An array of string the edit goes to.
- * @param {number} [limit=-1] - Upper limit of edit distance to be searched.
- * If negative, there is no limit.
- * @returns {Array<Insert|Delete>|undefined} The shortest edit script that turns `from` into `to`;
- * `undefined` if no edit script is found in the given range.
- */
- function shortestEditScript(from, to, limit = -1) {
- const fromLen = from.length;
- const toLen = to.length;
- const maxd = limit >= 0 ? Math.min(limit, fromLen + toLen) : fromLen + toLen;
- const mem = new Array(Math.min(maxd, fromLen) + Math.min(maxd, toLen) + 1);
- const offset = Math.min(maxd, fromLen);
- for (let d = 0; d <= maxd; d++) {
- const mink = d <= fromLen ? -d : d - 2 * fromLen;
- const maxk = d <= toLen ? d : -d + 2 * toLen;
- for (let k = mink; k <= maxk; k += 2) {
- let i;
- let script;
- if (d === 0) {
- i = 0;
- script = nil;
- }
- else if (k === -d) {
- i = mem[offset + k + 1].i + 1;
- script = mem[offset + k + 1].script.unshift(new Delete(i + k));
- }
- else if (k === d) {
- i = mem[offset + k - 1].i;
- script = mem[offset + k - 1].script.unshift(new Insert(i + k - 1, to[i + k - 1]));
- }
- else {
- const vi = mem[offset + k + 1].i + 1;
- const hi = mem[offset + k - 1].i;
- if (vi > hi) {
- i = vi;
- script = mem[offset + k + 1].script.unshift(new Delete(i + k));
- }
- else {
- i = hi;
- script = mem[offset + k - 1].script.unshift(new Insert(i + k - 1, to[i + k - 1]));
- }
- }
- while (i < fromLen && i + k < toLen && from[i] === to[i + k]) {
- i += 1;
- }
- if (k === toLen - fromLen && i === fromLen) {
- return script.toArray().reverse();
- }
- mem[offset + k] = { i, script };
- }
- }
- return undefined;
- }
- /**
- * The `ITextEditor` represents an interface to a text editor.
- *
- * @interface
- */
- class ITextEditor {
- /**
- * Gets the current cursor position.
- *
- * @returns {Point} A point object that represents the cursor position.
- */
- getCursorPosition() {
- throw new Error("Not implemented: getCursorPosition");
- }
- /**
- * Sets the cursor position to a specified one.
- *
- * @param {Point} pos - A point object which the cursor position is set to.
- * @returns {undefined}
- */
- setCursorPosition(pos) {
- throw new Error("Not implemented: setCursorPosition");
- }
- /**
- * Sets the selection range.
- * This method also expects the cursor position to be moved as the end of the selection range.
- *
- * @param {Range} range - A range object that describes a selection range.
- * @returns {undefined}
- */
- setSelectionRange(range) {
- throw new Error("Not implemented: setSelectionRange");
- }
- /**
- * Gets the last row index of the text editor.
- *
- * @returns {number} The last row index.
- */
- getLastRow() {
- throw new Error("Not implemented: getLastRow");
- }
- /**
- * Checks if the editor accepts a table at a row to be editted.
- * It should return `false` if, for example, the row is in a code block (not Markdown).
- *
- * @param {number} row - A row index in the text editor.
- * @returns {boolean} `true` if the table at the row can be editted.
- */
- acceptsTableEdit(row) {
- throw new Error("Not implemented: acceptsTableEdit");
- }
- /**
- * Gets a line string at a row.
- *
- * @param {number} row - Row index, starts from `0`.
- * @returns {string} The line at the specified row.
- * The line must not contain an EOL like `"\n"` or `"\r"`.
- */
- getLine(row) {
- throw new Error("Not implemented: getLine");
- }
- /**
- * Inserts a line at a specified row.
- *
- * @param {number} row - Row index, starts from `0`.
- * @param {string} line - A string to be inserted.
- * This must not contain an EOL like `"\n"` or `"\r"`.
- * @return {undefined}
- */
- insertLine(row, line) {
- throw new Error("Not implemented: insertLine");
- }
- /**
- * Deletes a line at a specified row.
- *
- * @param {number} row - Row index, starts from `0`.
- * @returns {undefined}
- */
- deleteLine(row) {
- throw new Error("Not implemented: deleteLine");
- }
- /**
- * Replace lines in a specified range.
- *
- * @param {number} startRow - Start row index, starts from `0`.
- * @param {number} endRow - End row index.
- * Lines from `startRow` to `endRow - 1` is replaced.
- * @param {Array<string>} lines - An array of string.
- * Each strings must not contain an EOL like `"\n"` or `"\r"`.
- * @returns {undefined}
- */
- replaceLines(startRow, endRow, lines) {
- throw new Error("Not implemented: replaceLines");
- }
- /**
- * Batches multiple operations as a single undo/redo step.
- *
- * @param {Function} func - A callback function that executes some operations on the text editor.
- * @returns {undefined}
- */
- transact(func) {
- throw new Error("Not implemented: transact");
- }
- }
- /**
- * Reads a property of an object if exists; otherwise uses a default value.
- *
- * @private
- * @param {*} obj - An object. If a non-object value is specified, the default value is used.
- * @param {string} key - A key (or property name).
- * @param {*} defaultVal - A default value that is used when a value does not exist.
- * @returns {*} A read value or the default value.
- */
- function _value(obj, key, defaultVal) {
- return (typeof obj === "object" && obj !== null && obj[key] !== undefined)
- ? obj[key]
- : defaultVal;
- }
- /**
- * Reads multiple properties of an object if exists; otherwise uses default values.
- *
- * @private
- * @param {*} obj - An object. If a non-object value is specified, the default value is used.
- * @param {Object} keys - An object that consists of pairs of a key and a default value.
- * @returns {Object} A new object that contains read values.
- */
- function _values(obj, keys) {
- const res = {};
- for (const [key, defaultVal] of Object.entries(keys)) {
- res[key] = _value(obj, key, defaultVal);
- }
- return res;
- }
- /**
- * Reads options for the formatter from an object.
- * The default values are used for options that are not specified.
- *
- * @param {Object} obj - An object containing options.
- * The available options and default values are listed below.
- *
- * | property name | type | description | default value |
- * | ------------------- | ------------------------ | ------------------------------------------------------- | ------------------------ |
- * | `formatType` | {@link FormatType} | Format type, normal or weak. | `FormatType.NORMAL` |
- * | `minDelimiterWidth` | {@link number} | Minimum width of delimiters. | `3` |
- * | `defaultAlignment` | {@link DefaultAlignment} | Default alignment of columns. | `DefaultAlignment.LEFT` |
- * | `headerAlignment` | {@link HeaderAlignment} | Alignment of header cells. | `HeaderAlignment.FOLLOW` |
- * | `textWidthOptions` | {@link Object} | An object containing options for computing text widths. | |
- * | `smartCursor` | {@link boolean} | Enables "Smart Cursor" feature. | `false` |
- *
- * The available options for `obj.textWidthOptions` are the following ones.
- *
- * | property name | type | description | default value |
- * | ----------------- | --------------------------------- | ----------------------------------------------------- | ------------- |
- * | `normalize` | {@link boolean} | Normalizes texts before computing text widths. | `true` |
- * | `wideChars` | {@link Set}<{@link string}> | A set of characters that should be treated as wide. | `new Set()` |
- * | `narrowChars` | {@link Set}<{@link string}> | A set of characters that should be treated as narrow. | `new Set()` |
- * | `ambiguousAsWide` | {@link boolean} | Treats East Asian Ambiguous characters as wide. | `false` |
- *
- * @returns {Object} - An object that contains complete options.
- */
- function options(obj) {
- const res = _values(obj, {
- formatType : FormatType.NORMAL,
- minDelimiterWidth: 3,
- defaultAlignment : DefaultAlignment.LEFT,
- headerAlignment : HeaderAlignment.FOLLOW,
- smartCursor : false
- });
- res.textWidthOptions = _values(obj.textWidthOptions, {
- normalize : true,
- wideChars : new Set(),
- narrowChars : new Set(),
- ambiguousAsWide: false
- });
- return res;
- }
- /**
- * Checks if a line is a table row.
- *
- * @private
- * @param {string} line - A string.
- * @returns {boolean} `true` if the given line starts with a pipe `|`.
- */
- function _isTableRow(line) {
- return line.trimLeft()[0] === "|";
- }
- /**
- * Computes new focus offset from information of completed and formatted tables.
- *
- * @private
- * @param {Focus} focus - A focus.
- * @param {Table} table - A completed but not formatted table with original cell contents.
- * @param {Object} formatted - Information of the formatted table.
- * @param {boolean} moved - Indicates whether the focus position is moved by a command or not.
- * @returns {number}
- */
- function _computeNewOffset(focus, table, formatted, moved) {
- if (moved) {
- const formattedFocusedCell = formatted.table.getFocusedCell(focus);
- if (formattedFocusedCell !== undefined) {
- return formattedFocusedCell.computeRawOffset(0);
- }
- else {
- return focus.column < 0 ? formatted.marginLeft.length : 0;
- }
- }
- else {
- const focusedCell = table.getFocusedCell(focus);
- const formattedFocusedCell = formatted.table.getFocusedCell(focus);
- if (focusedCell !== undefined && formattedFocusedCell !== undefined) {
- const contentOffset = Math.min(
- focusedCell.computeContentOffset(focus.offset),
- formattedFocusedCell.content.length
- );
- return formattedFocusedCell.computeRawOffset(contentOffset);
- }
- else {
- return focus.column < 0 ? formatted.marginLeft.length : 0;
- }
- }
- }
- /**
- * The `TableEditor` class is at the center of the markdown-table-editor.
- * When a command is executed, it reads a table from the text editor, does some operation on the
- * table, and then apply the result to the text editor.
- *
- * To use this class, the text editor (or an interface to it) must implement {@link ITextEditor}.
- */
- class TableEditor {
- /**
- * Creates a new table editor instance.
- *
- * @param {ITextEditor} textEditor - A text editor interface.
- */
- constructor(textEditor) {
- /** @private */
- this._textEditor = textEditor;
- // smart cursor
- /** @private */
- this._scActive = false;
- /** @private */
- this._scTablePos = null;
- /** @private */
- this._scStartFocus = null;
- /** @private */
- this._scLastFocus = null;
- }
- /**
- * Resets the smart cursor.
- * Call this method when the table editor is inactivated.
- *
- * @returns {undefined}
- */
- resetSmartCursor() {
- this._scActive = false;
- }
- /**
- * Checks if the cursor is in a table row.
- * This is useful to check whether the table editor should be activated or not.
- *
- * @returns {boolean} `true` if the cursor is in a table row.
- */
- cursorIsInTable() {
- const pos = this._textEditor.getCursorPosition();
- return this._textEditor.acceptsTableEdit(pos.row)
- && _isTableRow(this._textEditor.getLine(pos.row));
- }
- /**
- * Finds a table under the current cursor position.
- *
- * @private
- * @returns {Object|undefined} An object that contains information about the table;
- * `undefined` if there is no table.
- * The return object contains the properties listed in the table.
- *
- * | property name | type | description |
- * | --------------- | ----------------------------------- | ------------------------------------------------------------------------ |
- * | `range` | {@link Range} | The range of the table. |
- * | `lines` | {@link Array}<{@link string}> | An array of the lines in the range. |
- * | `table` | {@link Table} | A table object read from the text editor. |
- * | `focus` | {@link Focus} | A focus object that represents the current cursor position in the table. |
- */
- _findTable() {
- const pos = this._textEditor.getCursorPosition();
- const lastRow = this._textEditor.getLastRow();
- const lines = [];
- let startRow = pos.row;
- let endRow = pos.row;
- // current line
- {
- const line = this._textEditor.getLine(pos.row);
- if (!this._textEditor.acceptsTableEdit(pos.row) || !_isTableRow(line)) {
- return undefined;
- }
- lines.push(line);
- }
- // previous lines
- for (let row = pos.row - 1; row >= 0; row--) {
- const line = this._textEditor.getLine(row);
- if (!this._textEditor.acceptsTableEdit(row) || !_isTableRow(line)) {
- break;
- }
- lines.unshift(line);
- startRow = row;
- }
- // next lines
- for (let row = pos.row + 1; row <= lastRow; row++) {
- const line = this._textEditor.getLine(row);
- if (!this._textEditor.acceptsTableEdit(row) || !_isTableRow(line)) {
- break;
- }
- lines.push(line);
- endRow = row;
- }
- const range = new Range(
- new Point(startRow, 0),
- new Point(endRow, lines[lines.length - 1].length)
- );
- const table = readTable(lines);
- const focus = table.focusOfPosition(pos, startRow);
- return { range, lines, table, focus };
- }
- /**
- * Finds a table and does an operation with it.
- *
- * @private
- * @param {Function} func - A function that does some operation on table information obtained by
- * {@link TableEditor#_findTable}.
- * @returns {undefined}
- */
- _withTable(func) {
- const info = this._findTable();
- if (info === undefined) {
- return;
- }
- func(info);
- }
- /**
- * Updates lines in a given range in the text editor.
- *
- * @private
- * @param {number} startRow - Start row index, starts from `0`.
- * @param {number} endRow - End row index.
- * Lines from `startRow` to `endRow - 1` are replaced.
- * @param {Array<string>} newLines - New lines.
- * @param {Array<string>} [oldLines=undefined] - Old lines to be replaced.
- * @returns {undefined}
- */
- _updateLines(startRow, endRow, newLines, oldLines = undefined) {
- if (oldLines !== undefined) {
- // apply the shortest edit script
- // if a table is edited in a normal manner, the edit distance never exceeds 3
- const ses = shortestEditScript(oldLines, newLines, 3);
- if (ses !== undefined) {
- applyEditScript(this._textEditor, ses, startRow);
- return;
- }
- }
- this._textEditor.replaceLines(startRow, endRow, newLines);
- }
- /**
- * Moves the cursor position to the focused cell,
- *
- * @private
- * @param {number} startRow - Row index where the table starts in the text editor.
- * @param {Table} table - A table.
- * @param {Focus} focus - A focus to which the cursor will be moved.
- * @returns {undefined}
- */
- _moveToFocus(startRow, table, focus) {
- const pos = table.positionOfFocus(focus, startRow);
- if (pos !== undefined) {
- this._textEditor.setCursorPosition(pos);
- }
- }
- /**
- * Selects the focused cell.
- * If the cell has no content to be selected, then just moves the cursor position.
- *
- * @private
- * @param {number} startRow - Row index where the table starts in the text editor.
- * @param {Table} table - A table.
- * @param {Focus} focus - A focus to be selected.
- * @returns {undefined}
- */
- _selectFocus(startRow, table, focus) {
- const range = table.selectionRangeOfFocus(focus, startRow);
- if (range !== undefined) {
- this._textEditor.setSelectionRange(range);
- }
- else {
- this._moveToFocus(startRow, table, focus);
- }
- }
- /**
- * Formats the table under the cursor.
- *
- * @param {Object} options - See {@link options}.
- * @returns {undefined}
- */
- format(options) {
- this._withTable(({ range, lines, table, focus }) => {
- let newFocus = focus;
- // complete
- const completed = completeTable(table, options);
- if (completed.delimiterInserted && newFocus.row > 0) {
- newFocus = newFocus.setRow(newFocus.row + 1);
- }
- // format
- const formatted = formatTable(completed.table, options);
- newFocus = newFocus.setOffset(_computeNewOffset(newFocus, completed.table, formatted, false));
- // apply
- this._textEditor.transact(() => {
- this._updateLines(range.start.row, range.end.row + 1, formatted.table.toLines(), lines);
- this._moveToFocus(range.start.row, formatted.table, newFocus);
- });
- });
- }
- /**
- * Formats and escapes from the table.
- *
- * @param {Object} options - See {@link options}.
- * @returns {undefined}
- */
- escape(options) {
- this._withTable(({ range, lines, table, focus }) => {
- // complete
- const completed = completeTable(table, options);
- // format
- const formatted = formatTable(completed.table, options);
- // apply
- const newPos = new Point(range.end.row + (completed.delimiterInserted ? 2 : 1), 0);
- this._textEditor.transact(() => {
- this._updateLines(range.start.row, range.end.row + 1, formatted.table.toLines(), lines);
- if (newPos.row > this._textEditor.getLastRow()) {
- this._textEditor.insertLine(newPos.row, "");
- }
- this._textEditor.setCursorPosition(newPos);
- });
- this.resetSmartCursor();
- });
- }
- /**
- * Alters the alignment of the focused column.
- *
- * @param {Alignment} alignment - New alignment.
- * @param {Object} options - See {@link options}.
- * @returns {undefined}
- */
- alignColumn(alignment, options) {
- this._withTable(({ range, lines, table, focus }) => {
- let newFocus = focus;
- // complete
- const completed = completeTable(table, options);
- if (completed.delimiterInserted && newFocus.row > 0) {
- newFocus = newFocus.setRow(newFocus.row + 1);
- }
- // alter alignment
- let altered = completed.table;
- if (0 <= newFocus.column && newFocus.column <= altered.getHeaderWidth() - 1) {
- altered = alterAlignment(completed.table, newFocus.column, alignment, options);
- }
- // format
- const formatted = formatTable(altered, options);
- newFocus = newFocus.setOffset(_computeNewOffset(newFocus, completed.table, formatted, false));
- // apply
- this._textEditor.transact(() => {
- this._updateLines(range.start.row, range.end.row + 1, formatted.table.toLines(), lines);
- this._moveToFocus(range.start.row, formatted.table, newFocus);
- });
- });
- }
- /**
- * Selects the focused cell content.
- *
- * @param {Object} options - See {@link options}.
- * @returns {undefined}
- */
- selectCell(options) {
- this._withTable(({ range, lines, table, focus }) => {
- let newFocus = focus;
- // complete
- const completed = completeTable(table, options);
- if (completed.delimiterInserted && newFocus.row > 0) {
- newFocus = newFocus.setRow(newFocus.row + 1);
- }
- // format
- const formatted = formatTable(completed.table, options);
- newFocus = newFocus.setOffset(_computeNewOffset(newFocus, completed.table, formatted, false));
- // apply
- this._textEditor.transact(() => {
- this._updateLines(range.start.row, range.end.row + 1, formatted.table.toLines(), lines);
- this._selectFocus(range.start.row, formatted.table, newFocus);
- });
- });
- }
- /**
- * Moves the focus to another cell.
- *
- * @param {number} rowOffset - Offset in row.
- * @param {number} columnOffset - Offset in column.
- * @param {Object} options - See {@link options}.
- * @returns {undefined}
- */
- moveFocus(rowOffset, columnOffset, options) {
- this._withTable(({ range, lines, table, focus }) => {
- let newFocus = focus;
- // complete
- const completed = completeTable(table, options);
- if (completed.delimiterInserted && newFocus.row > 0) {
- newFocus = newFocus.setRow(newFocus.row + 1);
- }
- const startFocus = newFocus;
- // move focus
- if (rowOffset !== 0) {
- const height = completed.table.getHeight();
- // skip delimiter row
- const skip =
- newFocus.row < 1 && newFocus.row + rowOffset >= 1 ? 1
- : newFocus.row > 1 && newFocus.row + rowOffset <= 1 ? -1
- : 0;
- newFocus = newFocus.setRow(
- Math.min(Math.max(newFocus.row + rowOffset + skip, 0), height <= 2 ? 0 : height - 1)
- );
- }
- if (columnOffset !== 0) {
- const width = completed.table.getHeaderWidth();
- if (!(newFocus.column < 0 && columnOffset < 0)
- && !(newFocus.column > width - 1 && columnOffset > 0)) {
- newFocus = newFocus.setColumn(
- Math.min(Math.max(newFocus.column + columnOffset, 0), width - 1)
- );
- }
- }
- const moved = !newFocus.posEquals(startFocus);
- // format
- const formatted = formatTable(completed.table, options);
- newFocus = newFocus.setOffset(_computeNewOffset(newFocus, completed.table, formatted, moved));
- // apply
- this._textEditor.transact(() => {
- this._updateLines(range.start.row, range.end.row + 1, formatted.table.toLines(), lines);
- if (moved) {
- this._selectFocus(range.start.row, formatted.table, newFocus);
- }
- else {
- this._moveToFocus(range.start.row, formatted.table, newFocus);
- }
- });
- if (moved) {
- this.resetSmartCursor();
- }
- });
- }
- /**
- * Moves the focus to the next cell.
- *
- * @param {Object} options - See {@link options}.
- * @returns {undefined}
- */
- nextCell(options) {
- this._withTable(({ range, lines, table, focus }) => {
- // reset smart cursor if moved
- const focusMoved = (this._scTablePos !== null && !range.start.equals(this._scTablePos))
- || (this._scLastFocus !== null && !focus.posEquals(this._scLastFocus));
- if (this._scActive && focusMoved) {
- this.resetSmartCursor();
- }
- let newFocus = focus;
- // complete
- const completed = completeTable(table, options);
- if (completed.delimiterInserted && newFocus.row > 0) {
- newFocus = newFocus.setRow(newFocus.row + 1);
- }
- const startFocus = newFocus;
- let altered = completed.table;
- // move focus
- if (newFocus.row === 1) {
- // move to next row
- newFocus = newFocus.setRow(2);
- if (options.smartCursor) {
- if (newFocus.column < 0 || altered.getHeaderWidth() - 1 < newFocus.column) {
- newFocus = newFocus.setColumn(0);
- }
- }
- else {
- newFocus = newFocus.setColumn(0);
- }
- // insert an empty row if needed
- if (newFocus.row > altered.getHeight() - 1) {
- const row = new Array(altered.getHeaderWidth()).fill(new TableCell(""));
- altered = insertRow(altered, altered.getHeight(), new TableRow(row, "", ""));
- }
- }
- else {
- // insert an empty column if needed
- if (newFocus.column > altered.getHeaderWidth() - 1) {
- const column = new Array(altered.getHeight() - 1).fill(new TableCell(""));
- altered = insertColumn(altered, altered.getHeaderWidth(), column, options);
- }
- // move to next column
- newFocus = newFocus.setColumn(newFocus.column + 1);
- }
- // format
- const formatted = formatTable(altered, options);
- newFocus = newFocus.setOffset(_computeNewOffset(newFocus, altered, formatted, true));
- // apply
- const newLines = formatted.table.toLines();
- if (newFocus.column > formatted.table.getHeaderWidth() - 1) {
- // add margin
- newLines[newFocus.row] += " ";
- newFocus = newFocus.setOffset(1);
- }
- this._textEditor.transact(() => {
- this._updateLines(range.start.row, range.end.row + 1, newLines, lines);
- this._selectFocus(range.start.row, formatted.table, newFocus);
- });
- if (options.smartCursor) {
- if (!this._scActive) {
- // activate smart cursor
- this._scActive = true;
- this._scTablePos = range.start;
- if (startFocus.column < 0 || formatted.table.getHeaderWidth() - 1 < startFocus.column) {
- this._scStartFocus = new Focus(startFocus.row, 0, 0);
- }
- else {
- this._scStartFocus = startFocus;
- }
- }
- this._scLastFocus = newFocus;
- }
- });
- }
- /**
- * Moves the focus to the previous cell.
- *
- * @param {Object} options - See {@link options}.
- * @returns {undefined}
- */
- previousCell(options) {
- this._withTable(({ range, lines, table, focus }) => {
- let newFocus = focus;
- // complete
- const completed = completeTable(table, options);
- if (completed.delimiterInserted && newFocus.row > 0) {
- newFocus = newFocus.setRow(newFocus.row + 1);
- }
- const startFocus = newFocus;
- // move focus
- if (newFocus.row === 0) {
- if (newFocus.column > 0) {
- newFocus = newFocus.setColumn(newFocus.column - 1);
- }
- }
- else if (newFocus.row === 1) {
- newFocus = new Focus(0, completed.table.getHeaderWidth() - 1, newFocus.offset);
- }
- else {
- if (newFocus.column > 0) {
- newFocus = newFocus.setColumn(newFocus.column - 1);
- }
- else {
- newFocus = new Focus(
- newFocus.row === 2 ? 0 : newFocus.row - 1,
- completed.table.getHeaderWidth() - 1,
- newFocus.offset
- );
- }
- }
- const moved = !newFocus.posEquals(startFocus);
- // format
- const formatted = formatTable(completed.table, options);
- newFocus = newFocus.setOffset(_computeNewOffset(newFocus, completed.table, formatted, moved));
- // apply
- this._textEditor.transact(() => {
- this._updateLines(range.start.row, range.end.row + 1, formatted.table.toLines(), lines);
- if (moved) {
- this._selectFocus(range.start.row, formatted.table, newFocus);
- }
- else {
- this._moveToFocus(range.start.row, formatted.table, newFocus);
- }
- });
- if (moved) {
- this.resetSmartCursor();
- }
- });
- }
- /**
- * Moves the focus to the next row.
- *
- * @param {Object} options - See {@link options}.
- * @returns {undefined}
- */
- nextRow(options) {
- this._withTable(({ range, lines, table, focus }) => {
- // reset smart cursor if moved
- const focusMoved = (this._scTablePos !== null && !range.start.equals(this._scTablePos))
- || (this._scLastFocus !== null && !focus.posEquals(this._scLastFocus));
- if (this._scActive && focusMoved) {
- this.resetSmartCursor();
- }
- let newFocus = focus;
- // complete
- const completed = completeTable(table, options);
- if (completed.delimiterInserted && newFocus.row > 0) {
- newFocus = newFocus.setRow(newFocus.row + 1);
- }
- const startFocus = newFocus;
- let altered = completed.table;
- // move focus
- if (newFocus.row === 0) {
- newFocus = newFocus.setRow(2);
- }
- else {
- newFocus = newFocus.setRow(newFocus.row + 1);
- }
- if (options.smartCursor) {
- if (this._scActive) {
- newFocus = newFocus.setColumn(this._scStartFocus.column);
- }
- else if (newFocus.column < 0 || altered.getHeaderWidth() - 1 < newFocus.column) {
- newFocus = newFocus.setColumn(0);
- }
- }
- else {
- newFocus = newFocus.setColumn(0);
- }
- // insert empty row if needed
- if (newFocus.row > altered.getHeight() - 1) {
- const row = new Array(altered.getHeaderWidth()).fill(new TableCell(""));
- altered = insertRow(altered, altered.getHeight(), new TableRow(row, "", ""));
- }
- // format
- const formatted = formatTable(altered, options);
- newFocus = newFocus.setOffset(_computeNewOffset(newFocus, altered, formatted, true));
- // apply
- this._textEditor.transact(() => {
- this._updateLines(range.start.row, range.end.row + 1, formatted.table.toLines(), lines);
- this._selectFocus(range.start.row, formatted.table, newFocus);
- });
- if (options.smartCursor) {
- if (!this._scActive) {
- // activate smart cursor
- this._scActive = true;
- this._scTablePos = range.start;
- if (startFocus.column < 0 || formatted.table.getHeaderWidth() - 1 < startFocus.column) {
- this._scStartFocus = new Focus(startFocus.row, 0, 0);
- }
- else {
- this._scStartFocus = startFocus;
- }
- }
- this._scLastFocus = newFocus;
- }
- });
- }
- /**
- * Inserts an empty row at the current focus.
- *
- * @param {Object} options - See {@link options}.
- * @returns {undefined}
- */
- insertRow(options) {
- this._withTable(({ range, lines, table, focus }) => {
- let newFocus = focus;
- // complete
- const completed = completeTable(table, options);
- if (completed.delimiterInserted && newFocus.row > 0) {
- newFocus = newFocus.setRow(newFocus.row + 1);
- }
- // move focus
- if (newFocus.row <= 1) {
- newFocus = newFocus.setRow(2);
- }
- newFocus = newFocus.setColumn(0);
- // insert an empty row
- const row = new Array(completed.table.getHeaderWidth()).fill(new TableCell(""));
- const altered = insertRow(completed.table, newFocus.row, new TableRow(row, "", ""));
- // format
- const formatted = formatTable(altered, options);
- newFocus = newFocus.setOffset(_computeNewOffset(newFocus, altered, formatted, true));
- // apply
- this._textEditor.transact(() => {
- this._updateLines(range.start.row, range.end.row + 1, formatted.table.toLines(), lines);
- this._moveToFocus(range.start.row, formatted.table, newFocus);
- });
- this.resetSmartCursor();
- });
- }
- /**
- * Deletes a row at the current focus.
- *
- * @param {Object} options - See {@link options}.
- * @returns {undefined}
- */
- deleteRow(options) {
- this._withTable(({ range, lines, table, focus }) => {
- let newFocus = focus;
- // complete
- const completed = completeTable(table, options);
- if (completed.delimiterInserted && newFocus.row > 0) {
- newFocus = newFocus.setRow(newFocus.row + 1);
- }
- // delete a row
- let altered = completed.table;
- let moved = false;
- if (newFocus.row !== 1) {
- altered = deleteRow(altered, newFocus.row);
- moved = true;
- if (newFocus.row > altered.getHeight() - 1) {
- newFocus = newFocus.setRow(newFocus.row === 2 ? 0 : newFocus.row - 1);
- }
- }
- // format
- const formatted = formatTable(altered, options);
- newFocus = newFocus.setOffset(_computeNewOffset(newFocus, altered, formatted, moved));
- // apply
- this._textEditor.transact(() => {
- this._updateLines(range.start.row, range.end.row + 1, formatted.table.toLines(), lines);
- if (moved) {
- this._selectFocus(range.start.row, formatted.table, newFocus);
- }
- else {
- this._moveToFocus(range.start.row, formatted.table, newFocus);
- }
- });
- this.resetSmartCursor();
- });
- }
- /**
- * Moves the focused row by the specified offset.
- *
- * @param {number} offset - An offset the row is moved by.
- * @param {Object} options - See {@link options}.
- * @returns {undefined}
- */
- moveRow(offset, options) {
- this._withTable(({ range, lines, table, focus }) => {
- let newFocus = focus;
- // complete
- const completed = completeTable(table, options);
- if (completed.delimiterInserted && newFocus.row > 0) {
- newFocus = newFocus.setRow(newFocus.row + 1);
- }
- // move row
- let altered = completed.table;
- if (newFocus.row > 1) {
- const dest = Math.min(Math.max(newFocus.row + offset, 2), altered.getHeight() - 1);
- altered = moveRow(altered, newFocus.row, dest);
- newFocus = newFocus.setRow(dest);
- }
- // format
- const formatted = formatTable(altered, options);
- newFocus = newFocus.setOffset(_computeNewOffset(newFocus, altered, formatted, false));
- // apply
- this._textEditor.transact(() => {
- this._updateLines(range.start.row, range.end.row + 1, formatted.table.toLines(), lines);
- this._moveToFocus(range.start.row, formatted.table, newFocus);
- });
- this.resetSmartCursor();
- });
- }
- /**
- * Inserts an empty column at the current focus.
- *
- * @param {Object} options - See {@link options}.
- * @returns {undefined}
- */
- insertColumn(options) {
- this._withTable(({ range, lines, table, focus }) => {
- let newFocus = focus;
- // complete
- const completed = completeTable(table, options);
- if (completed.delimiterInserted && newFocus.row > 0) {
- newFocus = newFocus.setRow(newFocus.row + 1);
- }
- // move focus
- if (newFocus.row === 1) {
- newFocus = newFocus.setRow(0);
- }
- if (newFocus.column < 0) {
- newFocus = newFocus.setColumn(0);
- }
- // insert an empty column
- const column = new Array(completed.table.getHeight() - 1).fill(new TableCell(""));
- const altered = insertColumn(completed.table, newFocus.column, column, options);
- // format
- const formatted = formatTable(altered, options);
- newFocus = newFocus.setOffset(_computeNewOffset(newFocus, altered, formatted, true));
- // apply
- this._textEditor.transact(() => {
- this._updateLines(range.start.row, range.end.row + 1, formatted.table.toLines(), lines);
- this._moveToFocus(range.start.row, formatted.table, newFocus);
- });
- this.resetSmartCursor();
- });
- }
- /**
- * Deletes a column at the current focus.
- *
- * @param {Object} options - See {@link options}.
- * @returns {undefined}
- */
- deleteColumn(options) {
- this._withTable(({ range, lines, table, focus }) => {
- let newFocus = focus;
- // complete
- const completed = completeTable(table, options);
- if (completed.delimiterInserted && newFocus.row > 0) {
- newFocus = newFocus.setRow(newFocus.row + 1);
- }
- // move focus
- if (newFocus.row === 1) {
- newFocus = newFocus.setRow(0);
- }
- // delete a column
- let altered = completed.table;
- let moved = false;
- if (0 <= newFocus.column && newFocus.column <= altered.getHeaderWidth() - 1) {
- altered = deleteColumn(completed.table, newFocus.column, options);
- moved = true;
- if (newFocus.column > altered.getHeaderWidth() - 1) {
- newFocus = newFocus.setColumn(altered.getHeaderWidth() - 1);
- }
- }
- // format
- const formatted = formatTable(altered, options);
- newFocus = newFocus.setOffset(_computeNewOffset(newFocus, altered, formatted, moved));
- // apply
- this._textEditor.transact(() => {
- this._updateLines(range.start.row, range.end.row + 1, formatted.table.toLines(), lines);
- if (moved) {
- this._selectFocus(range.start.row, formatted.table, newFocus);
- }
- else {
- this._moveToFocus(range.start.row, formatted.table, newFocus);
- }
- });
- this.resetSmartCursor();
- });
- }
- /**
- * Moves the focused column by the specified offset.
- *
- * @param {number} offset - An offset the column is moved by.
- * @param {Object} options - See {@link options}.
- * @returns {undefined}
- */
- moveColumn(offset, options) {
- this._withTable(({ range, lines, table, focus }) => {
- let newFocus = focus;
- // complete
- const completed = completeTable(table, options);
- if (completed.delimiterInserted && newFocus.row > 0) {
- newFocus = newFocus.setRow(newFocus.row + 1);
- }
- // move column
- let altered = completed.table;
- if (0 <= newFocus.column && newFocus.column <= altered.getHeaderWidth() - 1) {
- const dest = Math.min(Math.max(newFocus.column + offset, 0), altered.getHeaderWidth() - 1);
- altered = moveColumn(altered, newFocus.column, dest);
- newFocus = newFocus.setColumn(dest);
- }
- // format
- const formatted = formatTable(altered, options);
- newFocus = newFocus.setOffset(_computeNewOffset(newFocus, altered, formatted, false));
- // apply
- this._textEditor.transact(() => {
- this._updateLines(range.start.row, range.end.row + 1, formatted.table.toLines(), lines);
- this._moveToFocus(range.start.row, formatted.table, newFocus);
- });
- this.resetSmartCursor();
- });
- }
- /**
- * Formats all the tables in the text editor.
- *
- * @param {Object} options - See {@link options}.
- * @returns {undefined}
- */
- formatAll(options) {
- this._textEditor.transact(() => {
- let pos = this._textEditor.getCursorPosition();
- let lines = [];
- let startRow = undefined;
- let lastRow = this._textEditor.getLastRow();
- // find tables
- for (let row = 0; row <= lastRow; row++) {
- const line = this._textEditor.getLine(row);
- if (this._textEditor.acceptsTableEdit(row) && _isTableRow(line)) {
- lines.push(line);
- if (startRow === undefined) {
- startRow = row;
- }
- }
- else if (startRow !== undefined) {
- // get table info
- const endRow = row - 1;
- const range = new Range(
- new Point(startRow, 0),
- new Point(endRow, lines[lines.length - 1].length)
- );
- const table = readTable(lines);
- const focus = table.focusOfPosition(pos, startRow);
- const focused = focus !== undefined;
- // format
- let newFocus = focus;
- const completed = completeTable(table, options);
- if (focused && completed.delimiterInserted && newFocus.row > 0) {
- newFocus = newFocus.setRow(newFocus.row + 1);
- }
- const formatted = formatTable(completed.table, options);
- if (focused) {
- newFocus = newFocus.setOffset(
- _computeNewOffset(newFocus, completed.table, formatted, false)
- );
- }
- // apply
- const newLines = formatted.table.toLines();
- this._updateLines(range.start.row, range.end.row + 1, newLines, lines);
- // update cursor position
- const diff = newLines.length - lines.length;
- if (focused) {
- pos = formatted.table.positionOfFocus(newFocus, startRow);
- }
- else if (pos.row > endRow) {
- pos = new Point(pos.row + diff, pos.column);
- }
- // reset
- lines = [];
- startRow = undefined;
- // update
- lastRow += diff;
- row += diff;
- }
- }
- if (startRow !== undefined) {
- // get table info
- const endRow = lastRow;
- const range = new Range(
- new Point(startRow, 0),
- new Point(endRow, lines[lines.length - 1].length)
- );
- const table = readTable(lines);
- const focus = table.focusOfPosition(pos, startRow);
- // format
- let newFocus = focus;
- const completed = completeTable(table, options);
- if (completed.delimiterInserted && newFocus.row > 0) {
- newFocus = newFocus.setRow(newFocus.row + 1);
- }
- const formatted = formatTable(completed.table, options);
- newFocus = newFocus.setOffset(
- _computeNewOffset(newFocus, completed.table, formatted, false)
- );
- // apply
- const newLines = formatted.table.toLines();
- this._updateLines(range.start.row, range.end.row + 1, newLines, lines);
- pos = formatted.table.positionOfFocus(newFocus, startRow);
- }
- this._textEditor.setCursorPosition(pos);
- });
- }
- }
- //# sourceMappingURL=mte-kernel.mjs.map
- /***/ }),
- /* 2 */
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return getEAW; });
- /* unused harmony export computeWidth */
- /*
- * This file is generated by a script. DO NOT EDIT BY HAND!
- */
- /*
- * This part (from BEGIN to END) is derived from the Unicode Data Files:
- *
- * UNICODE, INC. LICENSE AGREEMENT
- *
- * Copyright © 1991-2017 Unicode, Inc. All rights reserved.
- * Distributed under the Terms of Use in http://www.unicode.org/copyright.html.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of the Unicode data files and any associated documentation
- * (the "Data Files") or Unicode software and any associated documentation
- * (the "Software") to deal in the Data Files or Software
- * without restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, and/or sell copies of
- * the Data Files or Software, and to permit persons to whom the Data Files
- * or Software are furnished to do so, provided that either
- * (a) this copyright and permission notice appear with all copies
- * of the Data Files or Software, or
- * (b) this copyright and permission notice appear in associated
- * Documentation.
- *
- * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
- * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT OF THIRD PARTY RIGHTS.
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
- * NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
- * DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THE DATA FILES OR SOFTWARE.
- */
- /* BEGIN */
- var defs = [
- { start: 0, end: 31, prop: "N" },
- { start: 32, end: 126, prop: "Na" },
- { start: 127, end: 160, prop: "N" },
- { start: 161, end: 161, prop: "A" },
- { start: 162, end: 163, prop: "Na" },
- { start: 164, end: 164, prop: "A" },
- { start: 165, end: 166, prop: "Na" },
- { start: 167, end: 168, prop: "A" },
- { start: 169, end: 169, prop: "N" },
- { start: 170, end: 170, prop: "A" },
- { start: 171, end: 171, prop: "N" },
- { start: 172, end: 172, prop: "Na" },
- { start: 173, end: 174, prop: "A" },
- { start: 175, end: 175, prop: "Na" },
- { start: 176, end: 180, prop: "A" },
- { start: 181, end: 181, prop: "N" },
- { start: 182, end: 186, prop: "A" },
- { start: 187, end: 187, prop: "N" },
- { start: 188, end: 191, prop: "A" },
- { start: 192, end: 197, prop: "N" },
- { start: 198, end: 198, prop: "A" },
- { start: 199, end: 207, prop: "N" },
- { start: 208, end: 208, prop: "A" },
- { start: 209, end: 214, prop: "N" },
- { start: 215, end: 216, prop: "A" },
- { start: 217, end: 221, prop: "N" },
- { start: 222, end: 225, prop: "A" },
- { start: 226, end: 229, prop: "N" },
- { start: 230, end: 230, prop: "A" },
- { start: 231, end: 231, prop: "N" },
- { start: 232, end: 234, prop: "A" },
- { start: 235, end: 235, prop: "N" },
- { start: 236, end: 237, prop: "A" },
- { start: 238, end: 239, prop: "N" },
- { start: 240, end: 240, prop: "A" },
- { start: 241, end: 241, prop: "N" },
- { start: 242, end: 243, prop: "A" },
- { start: 244, end: 246, prop: "N" },
- { start: 247, end: 250, prop: "A" },
- { start: 251, end: 251, prop: "N" },
- { start: 252, end: 252, prop: "A" },
- { start: 253, end: 253, prop: "N" },
- { start: 254, end: 254, prop: "A" },
- { start: 255, end: 256, prop: "N" },
- { start: 257, end: 257, prop: "A" },
- { start: 258, end: 272, prop: "N" },
- { start: 273, end: 273, prop: "A" },
- { start: 274, end: 274, prop: "N" },
- { start: 275, end: 275, prop: "A" },
- { start: 276, end: 282, prop: "N" },
- { start: 283, end: 283, prop: "A" },
- { start: 284, end: 293, prop: "N" },
- { start: 294, end: 295, prop: "A" },
- { start: 296, end: 298, prop: "N" },
- { start: 299, end: 299, prop: "A" },
- { start: 300, end: 304, prop: "N" },
- { start: 305, end: 307, prop: "A" },
- { start: 308, end: 311, prop: "N" },
- { start: 312, end: 312, prop: "A" },
- { start: 313, end: 318, prop: "N" },
- { start: 319, end: 322, prop: "A" },
- { start: 323, end: 323, prop: "N" },
- { start: 324, end: 324, prop: "A" },
- { start: 325, end: 327, prop: "N" },
- { start: 328, end: 331, prop: "A" },
- { start: 332, end: 332, prop: "N" },
- { start: 333, end: 333, prop: "A" },
- { start: 334, end: 337, prop: "N" },
- { start: 338, end: 339, prop: "A" },
- { start: 340, end: 357, prop: "N" },
- { start: 358, end: 359, prop: "A" },
- { start: 360, end: 362, prop: "N" },
- { start: 363, end: 363, prop: "A" },
- { start: 364, end: 461, prop: "N" },
- { start: 462, end: 462, prop: "A" },
- { start: 463, end: 463, prop: "N" },
- { start: 464, end: 464, prop: "A" },
- { start: 465, end: 465, prop: "N" },
- { start: 466, end: 466, prop: "A" },
- { start: 467, end: 467, prop: "N" },
- { start: 468, end: 468, prop: "A" },
- { start: 469, end: 469, prop: "N" },
- { start: 470, end: 470, prop: "A" },
- { start: 471, end: 471, prop: "N" },
- { start: 472, end: 472, prop: "A" },
- { start: 473, end: 473, prop: "N" },
- { start: 474, end: 474, prop: "A" },
- { start: 475, end: 475, prop: "N" },
- { start: 476, end: 476, prop: "A" },
- { start: 477, end: 592, prop: "N" },
- { start: 593, end: 593, prop: "A" },
- { start: 594, end: 608, prop: "N" },
- { start: 609, end: 609, prop: "A" },
- { start: 610, end: 707, prop: "N" },
- { start: 708, end: 708, prop: "A" },
- { start: 709, end: 710, prop: "N" },
- { start: 711, end: 711, prop: "A" },
- { start: 712, end: 712, prop: "N" },
- { start: 713, end: 715, prop: "A" },
- { start: 716, end: 716, prop: "N" },
- { start: 717, end: 717, prop: "A" },
- { start: 718, end: 719, prop: "N" },
- { start: 720, end: 720, prop: "A" },
- { start: 721, end: 727, prop: "N" },
- { start: 728, end: 731, prop: "A" },
- { start: 732, end: 732, prop: "N" },
- { start: 733, end: 733, prop: "A" },
- { start: 734, end: 734, prop: "N" },
- { start: 735, end: 735, prop: "A" },
- { start: 736, end: 767, prop: "N" },
- { start: 768, end: 879, prop: "A" },
- { start: 880, end: 912, prop: "N" },
- { start: 913, end: 929, prop: "A" },
- { start: 930, end: 930, prop: "N" },
- { start: 931, end: 937, prop: "A" },
- { start: 938, end: 944, prop: "N" },
- { start: 945, end: 961, prop: "A" },
- { start: 962, end: 962, prop: "N" },
- { start: 963, end: 969, prop: "A" },
- { start: 970, end: 1024, prop: "N" },
- { start: 1025, end: 1025, prop: "A" },
- { start: 1026, end: 1039, prop: "N" },
- { start: 1040, end: 1103, prop: "A" },
- { start: 1104, end: 1104, prop: "N" },
- { start: 1105, end: 1105, prop: "A" },
- { start: 1106, end: 4351, prop: "N" },
- { start: 4352, end: 4447, prop: "W" },
- { start: 4448, end: 8207, prop: "N" },
- { start: 8208, end: 8208, prop: "A" },
- { start: 8209, end: 8210, prop: "N" },
- { start: 8211, end: 8214, prop: "A" },
- { start: 8215, end: 8215, prop: "N" },
- { start: 8216, end: 8217, prop: "A" },
- { start: 8218, end: 8219, prop: "N" },
- { start: 8220, end: 8221, prop: "A" },
- { start: 8222, end: 8223, prop: "N" },
- { start: 8224, end: 8226, prop: "A" },
- { start: 8227, end: 8227, prop: "N" },
- { start: 8228, end: 8231, prop: "A" },
- { start: 8232, end: 8239, prop: "N" },
- { start: 8240, end: 8240, prop: "A" },
- { start: 8241, end: 8241, prop: "N" },
- { start: 8242, end: 8243, prop: "A" },
- { start: 8244, end: 8244, prop: "N" },
- { start: 8245, end: 8245, prop: "A" },
- { start: 8246, end: 8250, prop: "N" },
- { start: 8251, end: 8251, prop: "A" },
- { start: 8252, end: 8253, prop: "N" },
- { start: 8254, end: 8254, prop: "A" },
- { start: 8255, end: 8307, prop: "N" },
- { start: 8308, end: 8308, prop: "A" },
- { start: 8309, end: 8318, prop: "N" },
- { start: 8319, end: 8319, prop: "A" },
- { start: 8320, end: 8320, prop: "N" },
- { start: 8321, end: 8324, prop: "A" },
- { start: 8325, end: 8360, prop: "N" },
- { start: 8361, end: 8361, prop: "H" },
- { start: 8362, end: 8363, prop: "N" },
- { start: 8364, end: 8364, prop: "A" },
- { start: 8365, end: 8450, prop: "N" },
- { start: 8451, end: 8451, prop: "A" },
- { start: 8452, end: 8452, prop: "N" },
- { start: 8453, end: 8453, prop: "A" },
- { start: 8454, end: 8456, prop: "N" },
- { start: 8457, end: 8457, prop: "A" },
- { start: 8458, end: 8466, prop: "N" },
- { start: 8467, end: 8467, prop: "A" },
- { start: 8468, end: 8469, prop: "N" },
- { start: 8470, end: 8470, prop: "A" },
- { start: 8471, end: 8480, prop: "N" },
- { start: 8481, end: 8482, prop: "A" },
- { start: 8483, end: 8485, prop: "N" },
- { start: 8486, end: 8486, prop: "A" },
- { start: 8487, end: 8490, prop: "N" },
- { start: 8491, end: 8491, prop: "A" },
- { start: 8492, end: 8530, prop: "N" },
- { start: 8531, end: 8532, prop: "A" },
- { start: 8533, end: 8538, prop: "N" },
- { start: 8539, end: 8542, prop: "A" },
- { start: 8543, end: 8543, prop: "N" },
- { start: 8544, end: 8555, prop: "A" },
- { start: 8556, end: 8559, prop: "N" },
- { start: 8560, end: 8569, prop: "A" },
- { start: 8570, end: 8584, prop: "N" },
- { start: 8585, end: 8585, prop: "A" },
- { start: 8586, end: 8591, prop: "N" },
- { start: 8592, end: 8601, prop: "A" },
- { start: 8602, end: 8631, prop: "N" },
- { start: 8632, end: 8633, prop: "A" },
- { start: 8634, end: 8657, prop: "N" },
- { start: 8658, end: 8658, prop: "A" },
- { start: 8659, end: 8659, prop: "N" },
- { start: 8660, end: 8660, prop: "A" },
- { start: 8661, end: 8678, prop: "N" },
- { start: 8679, end: 8679, prop: "A" },
- { start: 8680, end: 8703, prop: "N" },
- { start: 8704, end: 8704, prop: "A" },
- { start: 8705, end: 8705, prop: "N" },
- { start: 8706, end: 8707, prop: "A" },
- { start: 8708, end: 8710, prop: "N" },
- { start: 8711, end: 8712, prop: "A" },
- { start: 8713, end: 8714, prop: "N" },
- { start: 8715, end: 8715, prop: "A" },
- { start: 8716, end: 8718, prop: "N" },
- { start: 8719, end: 8719, prop: "A" },
- { start: 8720, end: 8720, prop: "N" },
- { start: 8721, end: 8721, prop: "A" },
- { start: 8722, end: 8724, prop: "N" },
- { start: 8725, end: 8725, prop: "A" },
- { start: 8726, end: 8729, prop: "N" },
- { start: 8730, end: 8730, prop: "A" },
- { start: 8731, end: 8732, prop: "N" },
- { start: 8733, end: 8736, prop: "A" },
- { start: 8737, end: 8738, prop: "N" },
- { start: 8739, end: 8739, prop: "A" },
- { start: 8740, end: 8740, prop: "N" },
- { start: 8741, end: 8741, prop: "A" },
- { start: 8742, end: 8742, prop: "N" },
- { start: 8743, end: 8748, prop: "A" },
- { start: 8749, end: 8749, prop: "N" },
- { start: 8750, end: 8750, prop: "A" },
- { start: 8751, end: 8755, prop: "N" },
- { start: 8756, end: 8759, prop: "A" },
- { start: 8760, end: 8763, prop: "N" },
- { start: 8764, end: 8765, prop: "A" },
- { start: 8766, end: 8775, prop: "N" },
- { start: 8776, end: 8776, prop: "A" },
- { start: 8777, end: 8779, prop: "N" },
- { start: 8780, end: 8780, prop: "A" },
- { start: 8781, end: 8785, prop: "N" },
- { start: 8786, end: 8786, prop: "A" },
- { start: 8787, end: 8799, prop: "N" },
- { start: 8800, end: 8801, prop: "A" },
- { start: 8802, end: 8803, prop: "N" },
- { start: 8804, end: 8807, prop: "A" },
- { start: 8808, end: 8809, prop: "N" },
- { start: 8810, end: 8811, prop: "A" },
- { start: 8812, end: 8813, prop: "N" },
- { start: 8814, end: 8815, prop: "A" },
- { start: 8816, end: 8833, prop: "N" },
- { start: 8834, end: 8835, prop: "A" },
- { start: 8836, end: 8837, prop: "N" },
- { start: 8838, end: 8839, prop: "A" },
- { start: 8840, end: 8852, prop: "N" },
- { start: 8853, end: 8853, prop: "A" },
- { start: 8854, end: 8856, prop: "N" },
- { start: 8857, end: 8857, prop: "A" },
- { start: 8858, end: 8868, prop: "N" },
- { start: 8869, end: 8869, prop: "A" },
- { start: 8870, end: 8894, prop: "N" },
- { start: 8895, end: 8895, prop: "A" },
- { start: 8896, end: 8977, prop: "N" },
- { start: 8978, end: 8978, prop: "A" },
- { start: 8979, end: 8985, prop: "N" },
- { start: 8986, end: 8987, prop: "W" },
- { start: 8988, end: 9000, prop: "N" },
- { start: 9001, end: 9002, prop: "W" },
- { start: 9003, end: 9192, prop: "N" },
- { start: 9193, end: 9196, prop: "W" },
- { start: 9197, end: 9199, prop: "N" },
- { start: 9200, end: 9200, prop: "W" },
- { start: 9201, end: 9202, prop: "N" },
- { start: 9203, end: 9203, prop: "W" },
- { start: 9204, end: 9311, prop: "N" },
- { start: 9312, end: 9449, prop: "A" },
- { start: 9450, end: 9450, prop: "N" },
- { start: 9451, end: 9547, prop: "A" },
- { start: 9548, end: 9551, prop: "N" },
- { start: 9552, end: 9587, prop: "A" },
- { start: 9588, end: 9599, prop: "N" },
- { start: 9600, end: 9615, prop: "A" },
- { start: 9616, end: 9617, prop: "N" },
- { start: 9618, end: 9621, prop: "A" },
- { start: 9622, end: 9631, prop: "N" },
- { start: 9632, end: 9633, prop: "A" },
- { start: 9634, end: 9634, prop: "N" },
- { start: 9635, end: 9641, prop: "A" },
- { start: 9642, end: 9649, prop: "N" },
- { start: 9650, end: 9651, prop: "A" },
- { start: 9652, end: 9653, prop: "N" },
- { start: 9654, end: 9655, prop: "A" },
- { start: 9656, end: 9659, prop: "N" },
- { start: 9660, end: 9661, prop: "A" },
- { start: 9662, end: 9663, prop: "N" },
- { start: 9664, end: 9665, prop: "A" },
- { start: 9666, end: 9669, prop: "N" },
- { start: 9670, end: 9672, prop: "A" },
- { start: 9673, end: 9674, prop: "N" },
- { start: 9675, end: 9675, prop: "A" },
- { start: 9676, end: 9677, prop: "N" },
- { start: 9678, end: 9681, prop: "A" },
- { start: 9682, end: 9697, prop: "N" },
- { start: 9698, end: 9701, prop: "A" },
- { start: 9702, end: 9710, prop: "N" },
- { start: 9711, end: 9711, prop: "A" },
- { start: 9712, end: 9724, prop: "N" },
- { start: 9725, end: 9726, prop: "W" },
- { start: 9727, end: 9732, prop: "N" },
- { start: 9733, end: 9734, prop: "A" },
- { start: 9735, end: 9736, prop: "N" },
- { start: 9737, end: 9737, prop: "A" },
- { start: 9738, end: 9741, prop: "N" },
- { start: 9742, end: 9743, prop: "A" },
- { start: 9744, end: 9747, prop: "N" },
- { start: 9748, end: 9749, prop: "W" },
- { start: 9750, end: 9755, prop: "N" },
- { start: 9756, end: 9756, prop: "A" },
- { start: 9757, end: 9757, prop: "N" },
- { start: 9758, end: 9758, prop: "A" },
- { start: 9759, end: 9791, prop: "N" },
- { start: 9792, end: 9792, prop: "A" },
- { start: 9793, end: 9793, prop: "N" },
- { start: 9794, end: 9794, prop: "A" },
- { start: 9795, end: 9799, prop: "N" },
- { start: 9800, end: 9811, prop: "W" },
- { start: 9812, end: 9823, prop: "N" },
- { start: 9824, end: 9825, prop: "A" },
- { start: 9826, end: 9826, prop: "N" },
- { start: 9827, end: 9829, prop: "A" },
- { start: 9830, end: 9830, prop: "N" },
- { start: 9831, end: 9834, prop: "A" },
- { start: 9835, end: 9835, prop: "N" },
- { start: 9836, end: 9837, prop: "A" },
- { start: 9838, end: 9838, prop: "N" },
- { start: 9839, end: 9839, prop: "A" },
- { start: 9840, end: 9854, prop: "N" },
- { start: 9855, end: 9855, prop: "W" },
- { start: 9856, end: 9874, prop: "N" },
- { start: 9875, end: 9875, prop: "W" },
- { start: 9876, end: 9885, prop: "N" },
- { start: 9886, end: 9887, prop: "A" },
- { start: 9888, end: 9888, prop: "N" },
- { start: 9889, end: 9889, prop: "W" },
- { start: 9890, end: 9897, prop: "N" },
- { start: 9898, end: 9899, prop: "W" },
- { start: 9900, end: 9916, prop: "N" },
- { start: 9917, end: 9918, prop: "W" },
- { start: 9919, end: 9919, prop: "A" },
- { start: 9920, end: 9923, prop: "N" },
- { start: 9924, end: 9925, prop: "W" },
- { start: 9926, end: 9933, prop: "A" },
- { start: 9934, end: 9934, prop: "W" },
- { start: 9935, end: 9939, prop: "A" },
- { start: 9940, end: 9940, prop: "W" },
- { start: 9941, end: 9953, prop: "A" },
- { start: 9954, end: 9954, prop: "N" },
- { start: 9955, end: 9955, prop: "A" },
- { start: 9956, end: 9959, prop: "N" },
- { start: 9960, end: 9961, prop: "A" },
- { start: 9962, end: 9962, prop: "W" },
- { start: 9963, end: 9969, prop: "A" },
- { start: 9970, end: 9971, prop: "W" },
- { start: 9972, end: 9972, prop: "A" },
- { start: 9973, end: 9973, prop: "W" },
- { start: 9974, end: 9977, prop: "A" },
- { start: 9978, end: 9978, prop: "W" },
- { start: 9979, end: 9980, prop: "A" },
- { start: 9981, end: 9981, prop: "W" },
- { start: 9982, end: 9983, prop: "A" },
- { start: 9984, end: 9988, prop: "N" },
- { start: 9989, end: 9989, prop: "W" },
- { start: 9990, end: 9993, prop: "N" },
- { start: 9994, end: 9995, prop: "W" },
- { start: 9996, end: 10023, prop: "N" },
- { start: 10024, end: 10024, prop: "W" },
- { start: 10025, end: 10044, prop: "N" },
- { start: 10045, end: 10045, prop: "A" },
- { start: 10046, end: 10059, prop: "N" },
- { start: 10060, end: 10060, prop: "W" },
- { start: 10061, end: 10061, prop: "N" },
- { start: 10062, end: 10062, prop: "W" },
- { start: 10063, end: 10066, prop: "N" },
- { start: 10067, end: 10069, prop: "W" },
- { start: 10070, end: 10070, prop: "N" },
- { start: 10071, end: 10071, prop: "W" },
- { start: 10072, end: 10101, prop: "N" },
- { start: 10102, end: 10111, prop: "A" },
- { start: 10112, end: 10132, prop: "N" },
- { start: 10133, end: 10135, prop: "W" },
- { start: 10136, end: 10159, prop: "N" },
- { start: 10160, end: 10160, prop: "W" },
- { start: 10161, end: 10174, prop: "N" },
- { start: 10175, end: 10175, prop: "W" },
- { start: 10176, end: 10213, prop: "N" },
- { start: 10214, end: 10221, prop: "Na" },
- { start: 10222, end: 10628, prop: "N" },
- { start: 10629, end: 10630, prop: "Na" },
- { start: 10631, end: 11034, prop: "N" },
- { start: 11035, end: 11036, prop: "W" },
- { start: 11037, end: 11087, prop: "N" },
- { start: 11088, end: 11088, prop: "W" },
- { start: 11089, end: 11092, prop: "N" },
- { start: 11093, end: 11093, prop: "W" },
- { start: 11094, end: 11097, prop: "A" },
- { start: 11098, end: 11903, prop: "N" },
- { start: 11904, end: 11929, prop: "W" },
- { start: 11930, end: 11930, prop: "N" },
- { start: 11931, end: 12019, prop: "W" },
- { start: 12020, end: 12031, prop: "N" },
- { start: 12032, end: 12245, prop: "W" },
- { start: 12246, end: 12271, prop: "N" },
- { start: 12272, end: 12283, prop: "W" },
- { start: 12284, end: 12287, prop: "N" },
- { start: 12288, end: 12288, prop: "F" },
- { start: 12289, end: 12350, prop: "W" },
- { start: 12351, end: 12352, prop: "N" },
- { start: 12353, end: 12438, prop: "W" },
- { start: 12439, end: 12440, prop: "N" },
- { start: 12441, end: 12543, prop: "W" },
- { start: 12544, end: 12548, prop: "N" },
- { start: 12549, end: 12590, prop: "W" },
- { start: 12591, end: 12592, prop: "N" },
- { start: 12593, end: 12686, prop: "W" },
- { start: 12687, end: 12687, prop: "N" },
- { start: 12688, end: 12730, prop: "W" },
- { start: 12731, end: 12735, prop: "N" },
- { start: 12736, end: 12771, prop: "W" },
- { start: 12772, end: 12783, prop: "N" },
- { start: 12784, end: 12830, prop: "W" },
- { start: 12831, end: 12831, prop: "N" },
- { start: 12832, end: 12871, prop: "W" },
- { start: 12872, end: 12879, prop: "A" },
- { start: 12880, end: 13054, prop: "W" },
- { start: 13055, end: 13055, prop: "N" },
- { start: 13056, end: 19903, prop: "W" },
- { start: 19904, end: 19967, prop: "N" },
- { start: 19968, end: 42124, prop: "W" },
- { start: 42125, end: 42127, prop: "N" },
- { start: 42128, end: 42182, prop: "W" },
- { start: 42183, end: 43359, prop: "N" },
- { start: 43360, end: 43388, prop: "W" },
- { start: 43389, end: 44031, prop: "N" },
- { start: 44032, end: 55203, prop: "W" },
- { start: 55204, end: 57343, prop: "N" },
- { start: 57344, end: 63743, prop: "A" },
- { start: 63744, end: 64255, prop: "W" },
- { start: 64256, end: 65023, prop: "N" },
- { start: 65024, end: 65039, prop: "A" },
- { start: 65040, end: 65049, prop: "W" },
- { start: 65050, end: 65071, prop: "N" },
- { start: 65072, end: 65106, prop: "W" },
- { start: 65107, end: 65107, prop: "N" },
- { start: 65108, end: 65126, prop: "W" },
- { start: 65127, end: 65127, prop: "N" },
- { start: 65128, end: 65131, prop: "W" },
- { start: 65132, end: 65280, prop: "N" },
- { start: 65281, end: 65376, prop: "F" },
- { start: 65377, end: 65470, prop: "H" },
- { start: 65471, end: 65473, prop: "N" },
- { start: 65474, end: 65479, prop: "H" },
- { start: 65480, end: 65481, prop: "N" },
- { start: 65482, end: 65487, prop: "H" },
- { start: 65488, end: 65489, prop: "N" },
- { start: 65490, end: 65495, prop: "H" },
- { start: 65496, end: 65497, prop: "N" },
- { start: 65498, end: 65500, prop: "H" },
- { start: 65501, end: 65503, prop: "N" },
- { start: 65504, end: 65510, prop: "F" },
- { start: 65511, end: 65511, prop: "N" },
- { start: 65512, end: 65518, prop: "H" },
- { start: 65519, end: 65532, prop: "N" },
- { start: 65533, end: 65533, prop: "A" },
- { start: 65534, end: 94175, prop: "N" },
- { start: 94176, end: 94177, prop: "W" },
- { start: 94178, end: 94207, prop: "N" },
- { start: 94208, end: 100332, prop: "W" },
- { start: 100333, end: 100351, prop: "N" },
- { start: 100352, end: 101106, prop: "W" },
- { start: 101107, end: 110591, prop: "N" },
- { start: 110592, end: 110878, prop: "W" },
- { start: 110879, end: 110959, prop: "N" },
- { start: 110960, end: 111355, prop: "W" },
- { start: 111356, end: 126979, prop: "N" },
- { start: 126980, end: 126980, prop: "W" },
- { start: 126981, end: 127182, prop: "N" },
- { start: 127183, end: 127183, prop: "W" },
- { start: 127184, end: 127231, prop: "N" },
- { start: 127232, end: 127242, prop: "A" },
- { start: 127243, end: 127247, prop: "N" },
- { start: 127248, end: 127277, prop: "A" },
- { start: 127278, end: 127279, prop: "N" },
- { start: 127280, end: 127337, prop: "A" },
- { start: 127338, end: 127343, prop: "N" },
- { start: 127344, end: 127373, prop: "A" },
- { start: 127374, end: 127374, prop: "W" },
- { start: 127375, end: 127376, prop: "A" },
- { start: 127377, end: 127386, prop: "W" },
- { start: 127387, end: 127404, prop: "A" },
- { start: 127405, end: 127487, prop: "N" },
- { start: 127488, end: 127490, prop: "W" },
- { start: 127491, end: 127503, prop: "N" },
- { start: 127504, end: 127547, prop: "W" },
- { start: 127548, end: 127551, prop: "N" },
- { start: 127552, end: 127560, prop: "W" },
- { start: 127561, end: 127567, prop: "N" },
- { start: 127568, end: 127569, prop: "W" },
- { start: 127570, end: 127583, prop: "N" },
- { start: 127584, end: 127589, prop: "W" },
- { start: 127590, end: 127743, prop: "N" },
- { start: 127744, end: 127776, prop: "W" },
- { start: 127777, end: 127788, prop: "N" },
- { start: 127789, end: 127797, prop: "W" },
- { start: 127798, end: 127798, prop: "N" },
- { start: 127799, end: 127868, prop: "W" },
- { start: 127869, end: 127869, prop: "N" },
- { start: 127870, end: 127891, prop: "W" },
- { start: 127892, end: 127903, prop: "N" },
- { start: 127904, end: 127946, prop: "W" },
- { start: 127947, end: 127950, prop: "N" },
- { start: 127951, end: 127955, prop: "W" },
- { start: 127956, end: 127967, prop: "N" },
- { start: 127968, end: 127984, prop: "W" },
- { start: 127985, end: 127987, prop: "N" },
- { start: 127988, end: 127988, prop: "W" },
- { start: 127989, end: 127991, prop: "N" },
- { start: 127992, end: 128062, prop: "W" },
- { start: 128063, end: 128063, prop: "N" },
- { start: 128064, end: 128064, prop: "W" },
- { start: 128065, end: 128065, prop: "N" },
- { start: 128066, end: 128252, prop: "W" },
- { start: 128253, end: 128254, prop: "N" },
- { start: 128255, end: 128317, prop: "W" },
- { start: 128318, end: 128330, prop: "N" },
- { start: 128331, end: 128334, prop: "W" },
- { start: 128335, end: 128335, prop: "N" },
- { start: 128336, end: 128359, prop: "W" },
- { start: 128360, end: 128377, prop: "N" },
- { start: 128378, end: 128378, prop: "W" },
- { start: 128379, end: 128404, prop: "N" },
- { start: 128405, end: 128406, prop: "W" },
- { start: 128407, end: 128419, prop: "N" },
- { start: 128420, end: 128420, prop: "W" },
- { start: 128421, end: 128506, prop: "N" },
- { start: 128507, end: 128591, prop: "W" },
- { start: 128592, end: 128639, prop: "N" },
- { start: 128640, end: 128709, prop: "W" },
- { start: 128710, end: 128715, prop: "N" },
- { start: 128716, end: 128716, prop: "W" },
- { start: 128717, end: 128719, prop: "N" },
- { start: 128720, end: 128722, prop: "W" },
- { start: 128723, end: 128746, prop: "N" },
- { start: 128747, end: 128748, prop: "W" },
- { start: 128749, end: 128755, prop: "N" },
- { start: 128756, end: 128760, prop: "W" },
- { start: 128761, end: 129295, prop: "N" },
- { start: 129296, end: 129342, prop: "W" },
- { start: 129343, end: 129343, prop: "N" },
- { start: 129344, end: 129356, prop: "W" },
- { start: 129357, end: 129359, prop: "N" },
- { start: 129360, end: 129387, prop: "W" },
- { start: 129388, end: 129407, prop: "N" },
- { start: 129408, end: 129431, prop: "W" },
- { start: 129432, end: 129471, prop: "N" },
- { start: 129472, end: 129472, prop: "W" },
- { start: 129473, end: 129487, prop: "N" },
- { start: 129488, end: 129510, prop: "W" },
- { start: 129511, end: 131071, prop: "N" },
- { start: 131072, end: 196605, prop: "W" },
- { start: 196606, end: 196607, prop: "N" },
- { start: 196608, end: 262141, prop: "W" },
- { start: 262142, end: 917759, prop: "N" },
- { start: 917760, end: 917999, prop: "A" },
- { start: 918000, end: 983039, prop: "N" },
- { start: 983040, end: 1048573, prop: "A" },
- { start: 1048574, end: 1048575, prop: "N" },
- { start: 1048576, end: 1114109, prop: "A" },
- { start: 1114110, end: 1114111, prop: "N" }
- ];
- /* END */
- /**
- * Returns The EAW property of a code point.
- * @private
- * @param {string} codePoint A code point
- * @return {string} The EAW property of the specified code point
- */
- function _getEAWOfCodePoint(codePoint) {
- let min = 0;
- let max = defs.length - 1;
- while (min !== max) {
- const i = min + ((max - min) >> 1);
- const def = defs[i];
- if (codePoint < def.start) {
- max = i - 1;
- }
- else if (codePoint > def.end) {
- min = i + 1;
- }
- else {
- return def.prop;
- }
- }
- return defs[min].prop;
- }
- /**
- * Returns the EAW property of a character.
- * @param {string} str A string in which the character is contained
- * @param {number} [at = 0] The position (in code unit) of the character in the string
- * @return {string} The EAW property of the specified character
- * @example
- * import { getEAW } from "meaw";
- *
- * // Narrow
- * assert(getEAW("A") === "Na");
- * // Wide
- * assert(getEAW("あ") === "W");
- * assert(getEAW("安") === "W");
- * assert(getEAW("🍣") === "W");
- * // Fullwidth
- * assert(getEAW("A") === "F");
- * // Halfwidth
- * assert(getEAW("ア") === "H");
- * // Ambiguous
- * assert(getEAW("∀") === "A");
- * assert(getEAW("→") === "A");
- * assert(getEAW("Ω") === "A");
- * assert(getEAW("Я") === "A");
- * // Neutral
- * assert(getEAW("ℵ") === "N");
- *
- * // a position (in code unit) can be specified
- * assert(getEAW("ℵAあAア∀", 2) === "W");
- */
- function getEAW(str, at) {
- const codePoint = str.codePointAt(at || 0);
- return codePoint === undefined
- ? undefined
- : _getEAWOfCodePoint(codePoint);
- }
- const defaultWidthMap = {
- "N" : 1,
- "Na": 1,
- "W" : 2,
- "F" : 2,
- "H" : 1,
- "A" : 1
- };
- /**
- * Computes width of a string based on the EAW properties of its characters.
- * By default characters with property Wide (W) or Fullwidth (F) are treated as wide (= 2)
- * and the others are as narrow (= 1)
- * @param {string} str A string to compute width
- * @param {Object<string, number> | undefined} [widthMap = undefined]
- * An object which represents a map from an EAW property to a character width
- * @return {number} The computed width
- * @example
- * import { computeWidth } from "meaw";
- *
- * assert(computeWidth("Aあ🍣Ω") === 6);
- * // custom widths can be specified by an object
- * assert(computeWidth("Aあ🍣Ω", { "A": 2 }) === 7);
- */
- function computeWidth(str, widthMap) {
- const map = widthMap
- ? Object.assign({}, defaultWidthMap, widthMap)
- : defaultWidthMap;
- let width = 0;
- for (const char of str) {
- width += map[getEAW(char)];
- }
- return width;
- }
- //# sourceMappingURL=meaw.es.js.map
- /***/ })
- /******/ ]);
- });
|