Skip to content

Commit

Permalink
Handle JSON files with value 'undefined' (#146)
Browse files Browse the repository at this point in the history
* Add: Handle JSON files with value 'undefined'

* Fix: next id value
Add: extend functionality to 'compress', 'validate' and 'treeview dialog'
Fix: regex ignores 'undefined' in arrays

* changes

* Fix: show correct selection if it contains another invalid text
Fix: checkbox overlapped
Fix: error in original ReportError code
  • Loading branch information
thomas694 authored Apr 30, 2023
1 parent 5f7fc54 commit 8920520
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 9 deletions.
14 changes: 8 additions & 6 deletions NppJSONViewer/NppJsonViewer/Define.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,13 @@ const TCHAR STR_INI_FORMATTING_LINE[] = TEXT("LINE_FORMATTING");
const TCHAR STR_INI_FORMATTING_INDENT[] = TEXT("INDENTATION");
const TCHAR STR_INI_FORMATTING_INDENTCOUNT[] = TEXT("INDENTATION_COUNT");

const TCHAR STR_INI_OTHER_SEC[] = TEXT("Others");
const TCHAR STR_INI_OTHER_FOLLOW_TAB[] = TEXT("FOLLOW_TAB");
const TCHAR STR_INI_OTHER_AUTO_FORMAT[] = TEXT("AUTO_FORMAT");
const TCHAR STR_INI_OTHER_USE_HIGHLIGHT[] = TEXT("USE_JSON_HIGHLIGHT");
const TCHAR STR_INI_OTHER_IGNORE_COMMENT[] = TEXT("IGNORE_COMMENT");
const TCHAR STR_INI_OTHER_IGNORE_COMMA[] = TEXT("IGNORE_TRAILLING_COMMA");
const TCHAR STR_INI_OTHER_SEC[] = TEXT("Others");
const TCHAR STR_INI_OTHER_FOLLOW_TAB[] = TEXT("FOLLOW_TAB");
const TCHAR STR_INI_OTHER_AUTO_FORMAT[] = TEXT("AUTO_FORMAT");
const TCHAR STR_INI_OTHER_USE_HIGHLIGHT[] = TEXT("USE_JSON_HIGHLIGHT");
const TCHAR STR_INI_OTHER_IGNORE_COMMENT[] = TEXT("IGNORE_COMMENT");
const TCHAR STR_INI_OTHER_IGNORE_COMMA[] = TEXT("IGNORE_TRAILLING_COMMA");
const TCHAR STR_INI_OTHER_REPLACE_UNDEFINED[] = TEXT("REPLACE_VALUE_UNDEFINED");

const TCHAR STR_SRCH_SEARCHING[] = TEXT("Searching for: ");
const TCHAR STR_SRCH_NOTFOUND[] = TEXT("Not found: ");
Expand Down Expand Up @@ -101,6 +102,7 @@ struct ParseOptions
{
bool bIgnoreComment = true;
bool bIgnoreTraillingComma = true;
bool bReplaceUndefined = false;
};

struct Setting
Expand Down
80 changes: 79 additions & 1 deletion NppJSONViewer/NppJsonViewer/JsonViewDlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "ScintillaEditor.h"
#include "Profile.h"
#include <format>
#include <regex>


JsonViewDlg::JsonViewDlg(HINSTANCE hIntance, const NppData &nppData, const bool &isReady, int nCmdId, std::shared_ptr<Setting> &pSetting)
Expand Down Expand Up @@ -80,6 +81,9 @@ void JsonViewDlg::FormatJson()
}
else
{
if (CheckForTokenUndefined(JsonViewDlg::eMethod::FormatJson, selectedText, res, NULL))
return;

ReportError(res);
}
}
Expand All @@ -94,13 +98,78 @@ void JsonViewDlg::CompressJson()
if (res.success)
{
m_Editor->ReplaceSelection(res.response);
HightlightAsJson();
}
else
{
if (CheckForTokenUndefined(JsonViewDlg::eMethod::GetCompressedJson, selectedText, res, NULL))
return;

ReportError(res);
}
}

bool JsonViewDlg::CheckForTokenUndefined(eMethod method, std::string selectedText, Result &res, HTREEITEM tree_root)
{
const auto [le, lf, indentChar, indentLen] = GetFormatSetting();

if (m_pSetting->parseOptions.bReplaceUndefined)
{
auto text = selectedText.substr(res.error_pos, 9);
std::transform(
text.begin(),
text.end(),
text.begin(),
[](unsigned char c)
{
return (unsigned char)std::tolower(c);
});
if (text == "undefined")
{
try
{
std::regex regex("([:\\[,])([\\s]*?)undefined([\\s,}]*?)", std::regex_constants::icase);
text = std::regex_replace(selectedText, regex, "$1$2null");
switch (method)
{
case eMethod::FormatJson:
res = JsonHandler(m_pSetting->parseOptions).FormatJson(text, le, lf, indentChar, indentLen);
break;
case eMethod::GetCompressedJson:
res = JsonHandler(m_pSetting->parseOptions).GetCompressedJson(text);
break;
case eMethod::ParseJson:
{
RapidJsonHandler handler(this, tree_root);
rapidjson::StringBuffer sb;
res = JsonHandler(m_pSetting->parseOptions).ParseJson<flgBaseReader>(text, sb, handler);
break;
}
case eMethod::ValidateJson:
res = JsonHandler(m_pSetting->parseOptions).ValidateJson(text);
break;
}
if (res.success)
{
m_Editor->ReplaceSelection((method == eMethod::ParseJson || method == eMethod::ValidateJson) ? text : res.response);
HightlightAsJson();
return true;
}
else
{
m_Editor->ReplaceSelection(text);
m_Editor->MakeSelection(m_Editor->GetSelectionStart(), static_cast<int>(text.length()));
m_Editor->RefreshSelectionPos();
}
}
catch (const std::exception&)
{
}
}
}
return false;
}

void JsonViewDlg::HandleTabActivated()
{
const bool bIsVisible = isCreated() && isVisible();
Expand Down Expand Up @@ -135,6 +204,12 @@ void JsonViewDlg::ValidateJson()
}
else
{
if (CheckForTokenUndefined(JsonViewDlg::eMethod::ValidateJson, selectedText, res, NULL))
{
ShowMessage(JSON_INFO_TITLE, JSON_ERR_VALIDATE_SUCCESS, MB_OK | MB_ICONINFORMATION);
return;
}

ReportError(res);
}
}
Expand Down Expand Up @@ -197,6 +272,9 @@ auto JsonViewDlg::PopulateTreeUsingSax(HTREEITEM tree_root, const std::string &j
Result res = JsonHandler(m_pSetting->parseOptions).ParseJson<flgBaseReader>(jsonText, sb, handler);
if (!res.success)
{
if (CheckForTokenUndefined(JsonViewDlg::eMethod::ParseJson, jsonText, res, tree_root))
return retVal;

// Intimate user
if (jsonText.empty())
{
Expand Down Expand Up @@ -603,7 +681,7 @@ void JsonViewDlg::ReportError(const Result &result)
{
// Mark the error position
size_t start = m_Editor->GetSelectionStart() + result.error_pos;
size_t end = start + m_Editor->GetSelectionEnd();
size_t end = m_Editor->GetSelectionEnd();
m_Editor->MakeSelection(start, end);

// Intimate user
Expand Down
10 changes: 10 additions & 0 deletions NppJSONViewer/NppJsonViewer/JsonViewDlg.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ class JsonViewDlg : public DockingDlgInterface
eSearch
};

enum class eMethod
{
FormatJson,
GetCompressedJson,
ParseJson,
ValidateJson
};

public:
JsonViewDlg(HINSTANCE hIntance, const NppData &nppData, const bool &isReady, int nCmdId, std::shared_ptr<Setting> &pSetting);
virtual ~JsonViewDlg();
Expand Down Expand Up @@ -70,6 +78,8 @@ class JsonViewDlg : public DockingDlgInterface

auto GetFormatSetting() const -> std::tuple<LE, LF, char, unsigned>;

bool CheckForTokenUndefined(eMethod method, std::string selectedText, Result &res, HTREEITEM tree_root);

protected:
virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam);

Expand Down
5 changes: 5 additions & 0 deletions NppJSONViewer/NppJsonViewer/Profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ bool ProfileSetting::GetSettings(Setting &info) const
if (bRetVal)
info.parseOptions.bIgnoreTraillingComma = static_cast<bool>(nVal);

bRetVal &= ReadValue(STR_INI_OTHER_SEC, STR_INI_OTHER_REPLACE_UNDEFINED, nVal, info.parseOptions.bReplaceUndefined);
if (bRetVal)
info.parseOptions.bReplaceUndefined = static_cast<bool>(nVal);

return bRetVal;
}

Expand All @@ -127,6 +131,7 @@ bool ProfileSetting::SetSettings(const Setting &info) const
bRetVal &= WriteValue(STR_INI_OTHER_SEC, STR_INI_OTHER_USE_HIGHLIGHT, info.bUseJsonHighlight);
bRetVal &= WriteValue(STR_INI_OTHER_SEC, STR_INI_OTHER_IGNORE_COMMENT, info.parseOptions.bIgnoreComment);
bRetVal &= WriteValue(STR_INI_OTHER_SEC, STR_INI_OTHER_IGNORE_COMMA, info.parseOptions.bIgnoreTraillingComma);
bRetVal &= WriteValue(STR_INI_OTHER_SEC, STR_INI_OTHER_REPLACE_UNDEFINED, info.parseOptions.bReplaceUndefined);

return bRetVal;
}
1 change: 0 additions & 1 deletion NppJSONViewer/NppJsonViewer/ScintillaEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ class ScintillaEditor
auto GetEOL() const -> unsigned;
auto GetIndent() const -> std::tuple<char, unsigned>;

private:
void RefreshSelectionPos();

private:
Expand Down
2 changes: 2 additions & 0 deletions NppJSONViewer/NppJsonViewer/SettingsDlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ bool SettingsDlg::Apply()
m_pSetting->bUseJsonHighlight = CUtility::GetCheckboxStatus(::GetDlgItem(_hSelf, IDC_CHK_JSON_HIGHLIGHT));
m_pSetting->parseOptions.bIgnoreTraillingComma = CUtility::GetCheckboxStatus(::GetDlgItem(_hSelf, IDC_CHK_IGNORE_COMMA));
m_pSetting->parseOptions.bIgnoreComment = CUtility::GetCheckboxStatus(::GetDlgItem(_hSelf, IDC_CHK_IGNORE_COMMENT));
m_pSetting->parseOptions.bReplaceUndefined = CUtility::GetCheckboxStatus(::GetDlgItem(_hSelf, IDC_CHK_REPLACE_UNDEFINED));

return WriteINI();
}
Expand Down Expand Up @@ -208,6 +209,7 @@ void SettingsDlg::InitDlg()
CUtility::SetCheckboxStatus(::GetDlgItem(_hSelf, IDC_CHK_JSON_HIGHLIGHT), m_pSetting->bUseJsonHighlight);
CUtility::SetCheckboxStatus(::GetDlgItem(_hSelf, IDC_CHK_IGNORE_COMMA), m_pSetting->parseOptions.bIgnoreTraillingComma);
CUtility::SetCheckboxStatus(::GetDlgItem(_hSelf, IDC_CHK_IGNORE_COMMENT), m_pSetting->parseOptions.bIgnoreComment);
CUtility::SetCheckboxStatus(::GetDlgItem(_hSelf, IDC_CHK_REPLACE_UNDEFINED), m_pSetting->parseOptions.bReplaceUndefined);
}

void SettingsDlg::ShowSpaceCountCtrls(bool bShow)
Expand Down
3 changes: 2 additions & 1 deletion NppJSONViewer/NppJsonViewer/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#define IDC_CHK_IGNORE_COMMA 1030
#define IDC_CHK_IGNORE_COMMENT 1031
#define IDC_CHK_JSON_HIGHLIGHT 1032
#define IDC_CHK_REPLACE_UNDEFINED 1033
#define IDM_COPY_TREEITEM 40001
#define IDM_COPY_NODENAME 40002
#define IDM_COPY_NODEVALUE 40003
Expand All @@ -54,7 +55,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 110
#define _APS_NEXT_COMMAND_VALUE 40007
#define _APS_NEXT_CONTROL_VALUE 1033
#define _APS_NEXT_CONTROL_VALUE 1034
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
1 change: 1 addition & 0 deletions NppJSONViewer/NppJsonViewer/resource.rc
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ BEGIN
CONTROL "Ignore trailing comma",IDC_CHK_IGNORE_COMMA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,33,140,10
CONTROL "Ignore comments in json",IDC_CHK_IGNORE_COMMENT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,46,140,10
CONTROL "Use json highlighting",IDC_CHK_JSON_HIGHLIGHT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,59,140,10
CONTROL "Replace value 'undefined' with 'null'",IDC_CHK_REPLACE_UNDEFINED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,72,140,10
GROUPBOX " Indentation: ",IDC_STATIC,153,7,140,43
CONTROL "Auto detect",IDC_RADIO_INDENT_AUTO,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,160,21,50,10
CONTROL "Use tab",IDC_RADIO_INDENT_TAB,"Button",BS_AUTORADIOBUTTON,240,21,50,10
Expand Down

0 comments on commit 8920520

Please sign in to comment.